Monday, January 20, 2014

From concept to reality in 6 weeks - final meeting prep

In preparing for the final iteration meeting with the customer, I took a few screenshots and created a Keynote presentation. Pretty simple stuff, just time consuming to make sure I have everything covered. At the client site I do not have an internet connection so I want to make sure I have it all covered.

On Friday, I saw a problem in trying to create the app as an installable package as I never received the email confirmation code. I found that odd since it has been working all along. The only thing I can think of is that somehow my license expired. I paid for the developer license so I have no real logical explanation. I need to have an installable image ready to go before the meeting either stored on my machine or on a thumb drive to give to the customer.

I search Ms. Google to find out why my two-step confirmation code never arrives. I found a Microsoft document explaining how to set this up as I definitely could not remember doing that. I went to Safari and logged into my live.com account. I went thru the steps to enable the two-step verification under my live account. I clicked on the icon in the upper hand corner for the Outlook web app. Then I clicked on "Security info" on the left hand side. I added my phone number as I need a fallback when my email does not work. I also added a second email account. The only odd thing about the process was installing an authenticator app on my iPhone. After doing that I had to scan the QR code on the screen to validate my iPhone. Once I had all of that setup, then when I tried to create a new package in Visual Studio, I opened the Authenticator app on my iPhone and entered the blue number on the screen. Now I should be all set from now on.

One final odd problem for the day as it is coming to a close. I cleaned and re-built the app and everything runs correctly, but when I build the Windows Store image it fails with 16 errors and those are all methods I renamed over the last two weeks. It must be stored in a file somewhere that I need to regenerate. Time to use Ms. Google again as I have not encountered these errors before. After much searching and searching and searching, I finally found the answer deeply embedded in a StackOverflow post. The only  way to fix the problem was to delete the "obj" folder and then rebuild the project solution. That is obviously to get around a VisualStudio bug as that does not make sense why VSE would cache such things when building release packages. I am just so glad I found the problem finally.

I finished the release build, made a ZIP file and now I am ready to go.

From concept to reality in 6 weeks - RECAP

This is a summary of what was done each day from start to finish, which included the second phase of the project:

Day 1 - buy a Windows 8.1 laptop with touch interface
Day 2 - get Windows Phone development environment working on Windows 8.1 Pro environment
Day 3 - learn about BingMaps and VisualStudio Express
Day 4 - learn how to load data from server using BackgroundTransfer
Day 5 - learn about Metro UI using XAML + 3rd party component libraries
Day 6 - read Windows Store app UX guidelines + using single Application Bar + first iteration meeting with client
Day 6.5 - create Microsoft developer account + learn how to submit app to Windows Store
Day 7 - custom application icons & fonts + UI layouts + create 1st deployable package to give to customer
Day 8 - learn about Windows 8 Application Lifecycle + how to use dialogs
Day 9 - retrieve live data from server and process as JSON and then display on BingMap
Day 9.5 - load free Perpetuum Windows Store controls
Day 11 - ask for more developer help to build custom controls + learn how to debug exceptions
Day 12 - parse all live data as JSON and display on BingMap as push pins
Day 13 - use Telerik DualRangeSlider + formatting numbers + learn LINQ
Day 14 - learn C# interfaces + create custom font using IcoMoon.io + learn how to create custom images dynamically in code
Day 15 - switch to BA3 mapping engine + learn how to do string manipulation in C#
Day 16 - generate dynamic markers with ImageMagick
Day 17 - check each image anchor point + explore how to install app outside Windows Store
Day 18 - figure out how to use and debug asynchronous methods + deploy outside Windows Store + how to read/write files locally on device
Day 19 - more success with LINQ + debug geographic issues with GPS coordinates
Day 20 - learn about notifications and bindings + how to use custom app colors
Day 21 - learn more details about strings + rewrite all of server download code to use HttpClient
Day 22 - deal with 500 error codes from server + change app so it works without internet connection by loading local files instead of loading data from server + centering map in geographic center of USA with extents to show some of Alaska
Day 23 - app stops working at most inopportune time
Day 24 - all 4 map layers working correctly + important customer iteration meeting + whole app in good working condition
Day 25 - use Telerik Date/Time controls + StackPanel compared to Grid layout + theming Telerik controls
Day 26 - list of all Metro controls + VisualStudio app reports + timing app usage using StopWatch class
Day 27 - prepare for final iteration meeting + create test data to validate all 4 layers on map

This was the start of Phase 2, since I ran out of the allotted money allowed for the initial project, I had to get customer approval before resuming on the left that remained that was not essential for the CES conference:

Day 28 - resolve some of related issues to uses of Telerik RangeSlider for filtering
Day 29 - property change notifications + pointer events
Day 30 - use Windows Store app Settings + saving Settings as local data
Day 31 - localizing date/time output + button FlyOut menus
Day 32 - live update at periodic intervals + mathematical formulas related to GPS coordinates
Day 33 - missing BA3 mapping functions + create temporary work arounds until BA3 can deliver updates
Day 34 - Windows Store app SearchBox + popup placement + working with collections to remove and find whether element already exists + more geographic mathematical formulas
Day 35 - major typo found in bearing calculations + BA3 mapping engine update
Day 36 - merge two collections + email issues + reboot to install patches
Day 37 - retry logic for server failures + ListView for search results

Friday, January 17, 2014

From concept to reality in 6 weeks - part 37

In many ways today is a sad day is it is the last day I have to work on the Windows Store app. To start the day off in the correct musical mood I am going to listen to "North Mississippi Allstars". Next week I am going to write a couple of summary blog entries to recap all of the things I learned from a couple of views.

For now I just need to wrap up and test as many of the features as I can. The beauty of working on my laptop is that it is not a simulator or emulator as the machine is also a touch device that is the target of this app. I don't expect to try any new C# stuff today but you never know...

The very first thing I encountered was numerous 500 and 502 server errors. I have ignored these long enough as I need to add some retry logic as they always seem to work when I try them in Safari on my Mac. When in the debugger I see an odd HResult code but that is not going to help me as I tried to look that up in the Microsoft error codes and it was not a match. The real ticket was looking up the HttpResponseCodes as that is very easy to retrieve. I set a a maximum number of times to retry so I never get into an infinite look when the server is not working at all or the internet connection fails. When that happens I make sure the progress dialog is closed and a MessageDialog is shown so the user sees the actual error message. That is my first error I have shown in the this app so I feel pretty good about that.

I have been testing the live updates for a while and found several issues that have to be fixed. When part of the data is filtered and new data arrives then the data is not stored correctly. That was pretty easy to fix. I was a bit worried at first as it seemed like a major problem.

Then I switched to changing the way search worked as it was only partially implemented. I need to match the iPad functionality but at the same time make it look better and act better. It is kind of late to do this but I am confident that it can be done. The first thing I want to do it make the search popup on the right hand side of the app (kind of like the Settings). It turns out that is way harder than it should be. I first tried to change the placement location as documented. When that did not work I tried looking for other answers but some were so complicated that it just did not seem like the right thing to do. In the end the solution was to set the HorizontalAlignment to be on the right side, but that pushed the whole popup off the screen. Then I set the HorizontalOffset to be the negative of the popup width and bingo all was resolved.

After trying a couple of different things using multiple StackedPanel and then a Grid to display the custom search results, I tried wrapping them both in a ScrollView but that was not a good idea. It was a good guess but totally the wrong thing to do. I abandoned everything I have done so far and looked up the GridView or ListView to learn about how they are different and which would be better for me. I decided ListView was better so I was off to explore a brand new part of a Windows Store app on my final day - sounds dangerous but it was just what I needed or so it seems. Thankfully the ListView quick start guide was perfect and I was up and running quickly. I created a new model class to hold the search results to be displayed in the ListView, which was a small subset of the observations data model. Perfectly simple and made perfect sense. As a first pass I just added a ToString method in my new model class and the data displayed correctly the first time! I guess I am getting the hang of this now.

I need to make it look stylish so I need to find the style template names. ListView has been around so that was too easy as they are all documented. I read up on the ListView guidelines to make sure I was not doing something odd. The only tricky thing was I needed to apply the style programmatically, which is not something I even know how to do. A quick search on the MSDN blog and solution was found and worked the first time. Then I switched as it seemed like my code was getting too complicated. I found an explanation of styling using a ListView.ItemTemplate. That is amazing how easy that is in XAML, so I deleted all of my C# code related to ListViewItems.

Now that my search results look beautiful, I need to figure out how to allow multiple selection, since the scrolling automatically works with the ListView as I don't have to deal with that nastiness. The only tricky part was figuring out how to deal with multiple selections in the SelectionChange handler.  The ListView has a SelectedItems property which is a collection of IList. I got into the debugger and found that these are actually a List of my SearchResult objects. This is going to just too easy. I add a button in the search to clear all selections just there can be many matches and I already know how to clear a list by calling SelectedItems.Clear()! I went back and read up on multiple selections to make sure I understood how they work. Some of these posts are pretty worthless but I found this gem talking about the ListView selections in just the right amount of detail. I went back into the original search auto-complete as that needs to change to just update the SelectedItems and I am sure it will just all work correctly. The real question is what happens if I try to add an item that is already selected a second time. And the answer is nothing - just as it should be - so perfect.

I had time to look a one last filter bug and squished that with some effort. I have been neglecting that one for a long time. That leaves one final bug that will just have to sit there so a while as I have run out of time and money to work on this project so I have to make one final tag in the GitHub repo and then make one final release build to give to the customer next week in my last visit.

Happy ending to a Friday!

Wednesday, January 15, 2014

From concept to reality in 6 weeks - part 36

This was not the way today was supposed to start out. I have had issues with my Mac Mail app and when I tried to send email this morning, I keep seeing the emails pile up in my Outbox. That was not supposed to be doing that for sure. I have two email accounts that I use that are tied to my HostMonster domains. After a struggle, I decided to delete the two internet accounts and just start over. I first went into HostMonster and changed the email passwords just to be safe that it was not password issues. I added both email accounts back in and they still did not work. I then went back into my HostMonster account and decided to look more closely at the settings and I had added the non-SSL accounts so once again I deleted both accounts and added them back in as SSL accounts. Then after Mail.app crashing multiple times, which I assume were due to the email account changes, I finally have my email back up and running and the emails sitting in my Outbox were all Sent. Hopefully this is not a sign for my day.

And I am going to try to restart the day by listening to "Of Monsters and Men" on Spotify since it was very nice listening to their songs while watching "The secret life of Walter Mitty" the other day. That should put me in the right frame of mind to get my tasks done early today - or at least I can hope.

My first new thing to learn about today was now to merge two list collections into a single collection. And what came to my rescue but LINQ yet again. It is THE most useful part of C# that I have encountered so far. If I think about collections in Java, ActionScript, Ruby, and Objective-C, then LINQ is definitely number one as it makes writing code so much more readable and just makes sense to me with very little training or reading documentation.

I keep forgetting that I am using a Windows machine. Today my Windows laptop was acting really strange so I remembered that I need to reboot it occasionally. I have only reboot a hand full of times in the months since I got the machine, which sounds really good, except for the fact when I rebooted today I had several updates that were waiting for a reboot to install. Last week when I reboot I have some SONY VAIO specific patches to install and since that day I have not had the problems with my display where the touch sensors stopped working after a while. I just get in the zone after using my Mac for so long that I forget about things like that. When I logged back into my laptop this time I saw a notification that I had a new Adobe Reader available also. All kinds of updates are happening - must be the full moon day coming up tonight.

Today was pretty much testing day as I wanted to make sure the live updates were working and when new data arrives every thing still works as expected. This requires loading the initial data and then waiting for the minimum live update time for updates to arrive and do stuff while the update is happening.

Tuesday, January 14, 2014

From concept to reality in 6 weeks - part 35

The project is definitely winding down now as the end is definitely in sight. I am so immersed in this project that I think of things at night in my sleep to fix the next day and the shocking thing is that they are good ideas and have been helping.

The first thing I need to do is verify that the very same data loaded from the server on the original Java app matching the iPad app which matches the Windows Store app. The first thing that got my attention was the heading I was using on the Windows Store app seemed off. I kept looking at the app running on my iPad mini and compared it to my Windows Store app and just could not figure it out. Finally I looked at the mathematics one more time and found the problem. The font used in VSE hid the fact that a zero (0) and eight (8) look very similar. For an angle I had 100 instead of 180 which will make a big difference. I finally had all of the data loading correctly and matching so that was a major accomplishment for today. These changes also will make one of the final tasks much easier to finish. But there is more that needs to be done...

Today's task was to finish what has been bothering me for 5 days now. I got a new mapping engine build and that fixed several of my problems. I looked at the documentation and found a much better way to simulate a flight path and so finally I am done with the task that has been bothering me way to long. What made it even better was that the code was about half the number of lines and so much easier to read. Mission complete.

The end of the day has come and I have a new page for all aviation formulas that I would ever need to know or care about, even though I was told by the mapping engine lead developer that some of them are incorrect and he has 100,000 pilots that back up his argument. Let's see who shall I believe? That is not hard at all as I pick the mapping engine developer every time as he has been wonderful in every way!

Monday, January 13, 2014

From concept to reality in 6 weeks - part 34

This week means it is time to start ramping down on this project for this current phase. I have a bunch of small tasks that would be nice to have completed, but they are going to have to be delayed to the end of this phase when I am sure I have more time left. The number one priority now is to complete the last 4 tasks that have to be down and leave all of the others to the end.

I tried a couple of things this morning that did not go so well. I thought I would try to change one of the styles in the SearchBox but since this is a new component I found little information on the style classes so had to refer to an article outside the standard MSDN network. I wanted to style the selected text in the SearchBox so it was not the default bright purple color. It is a pretty minor issue, so after trying a couple of different properties I gave up.

Then I thought it would be nice to place the search popup on the right hand side and that was not possible in the XAML as it required code behind window size calculations (after referring to the Popup Placement documentation), to I made an executive decision to leave it on the top left where all of the other popup dialogs are placed in this app.

The only simple success so far this morning was figuring out how to remove elements from a List Collection. One of the lists of data I am getting from the server contains data but it is not relevant for the other data I am getting from the server, so I need to trim the non-relevent data from the collection. A really bad idea is to loop thru the collection and call Remove as that messes up the next element retrieved. I waded thru one of the MSDN blogs and found the easiest solution to understand was to loop thru all of the collection finding the bad elements and then in a separate loop remove those elements. There is probably a more elegant way but it works and I only call this method once on a small set of data so it is good enough for me.

While on a success roll, I decided I wanted to change the SeachBox queries to not match at the start but anywhere in the string. I just switched "StartsWith" to IndexOf and that was pretty much done. Before leaving the search one last time I re-read the Quick Start guide on adding a search and using a SearchBox is much more flexible than the SearchPane so that was definitely the correct decision. Time to move on...

I contacted the mapping engine lead developer to discuss a couple of missing API's late last week so I am still waiting on them. This morning I sent him one more problem as I am able to crash the Windows Store app every time when I use the Settings service. Hopefully that will be resolved this week also before I wrap up the project.

Now I get to resume working on my geographic mathematics skills by reviewing the code at the bottom of the same page I was look at last week as I need to finish the task I have been working on and off for the last 4 working days.

This is a helpful site to help me figure out the distance in nautical miles between two points to check my calculations. Then I need to do some more Date arithmetic since the server always returns dates in UTC format and I have to always show them in local time. Just before I started on that I noticed that each of my threads exit with a code of 250 (0x103), so I looked that up to make sure nothing evil was happening. The documentation said that it was "ERROR_NO_MORE_ITEMS" so that is perfectly fine since those are my server requests ending.

I had another detour as I needed to send the system dump to the mapping engineer lead developer so he can be working on the crash. I can duplicate it easily so when the app crashes, I just went to the DEBUG menu and clicked on "Save Dump As..." at bottom of the menu. The only problem was that the resulting dump file was 262 MB. The compressed size was 79 MB so both are way too large for sending it by email. They have an FTP site set up so I transferred the file from my Windows laptop using my new $9.95 8 GB thumb drive to my Mac and then used a secure copy command using the port he gave me and the username/password combination.

Back to UTC problems. If you search for "utc time" using Ms. Google then she shows the current time in UTC time. This helps me debug my UTC server issues. As I expected there is a -5 hour time difference between where I am and Greenwich, England. All I had to do to fix all of my UTC problems was always pass a UTC time to get data from the server but when displaying the date/time information, I just do the following:

DateTimeFormatter formatter = new DateTimeFormatter(Preferences.DateTimeFormat);
string startDate = formatter.Format(data.First().Add(DateTimeOffset.Now.Offset));

This is not the normal way of using the Windows Store DateTimeOffset class as it supports ways to convert time from a UTC time to local time as long as the Kind property is set correctly, but in my case that is not set so I have to do special processing. As typically happens the above code looks so simple but that took me a while to reduce what I was doing to that simple level. The first thing I did was use the Subtract method instead of the Add method and what is amusing about that is that I was debugging this problem around noon and so the numbers looked very close but were off by two hours or so it seemed. It was actually off by by 5 hours in the wrong direction.


Saturday, January 11, 2014

From concept to reality in 6 weeks - part 33

I am resuming where I left off yesterday with writing C# code using the Objective-C code as a reference - within a couple of hours I should be done and then I have the rest of the day to test and validate every thing is working correctly. I have a couple of missing mapping engine APIs so that may be a challenge but I will get it as close as possible. I contacted the mapping engine lead developer and sent him an email of the missing APIs. He said he would add them for me in the next couple of weeks so I will be patient in that regard and trust him since he is totally trustworthy and is a great developer. I am happy I got to know him better during this project.

My first attempt was a pretty big failure as the mapping engine displayed a spinning globe looking down from the north pole. At least I can learn something from this. I looked that up and the north pole means a location of 90° N so somehow my location is messed up. I got into the debugger and check the location value I was setting and it was way off, so much so I am do not even want to mention what the lat/long values are. OK, for the sake of confession I will say the value was (770+, 4337+) - I am pretty sure there is no planet where those values are correct. Now I get to track down what I did wrong. At least the heading value was correct at 255°, so at least something is correct. I think the best plan of action is to go line by line and recheck what I did and maybe I will find some problems. As I was creating the C# code yesterday I was wondering about the order of the points so maybe that is different from the iPad app, but that is not my immediate problem. There is no utility I can use so I just need to take some time and compare the files. I have Xcode up on my Mac and VSE on Windows and need to slowly look at the 330 lines of Objective-C code and compare it with the 291 of C# code.

The above two paragraphs describe what I was able to do in 3 hours of work time. Not that great, as I had so many distractions yesterday and fixing this task requires complete concentration. Today is yet another new day and it is pretty quiet around work so just the environment I need for this task. I have a late day meeting so yesterday and today will count for a full day's work so I am reusing this post.

Comparing the Objective-C to C# line by line did not immediately uncover any problems until I saw the line that I was using as a work around since the version of the mapping engine that I am using is missing a method I need. The version I borrowed from http://www.movable-type.co.uk/scripts/latlong.html required a closer look and then I found the major bug that was causing most of my problems. I was passing the latitude and longitude in degrees instead of radians, so that obviously is going to be bad news when calling trig functions! I moved all of the trig functions to a separate class so I don't have to remember such things ever again. Then as I inspected location values in the debugger I noticed NaN being returned, so that is pretty evil. In the approximation function I was using I was getting the evil NaN when I passed in the same location twice. That was easy to fix as I went back to original and that problem was fixed as quick as you can say "Not a Number".

Again I did not get to finish the feature I was working on but at last I fixe most of the problems and now it is working partially so it will have to wait for next week.