Imagine Cup 2013

We came to the competition with a very simple application and then got to the World Wide Final. I did not expect that, but I believed we were worth that place in the top 3 because I believed the judges must have seen what we were trying to achieve: we were trying to make our phones handier and make life simpler; we did not try to just showcase technology. Then I arrived in Russia, super proud of our project. I prepared my presentation before all the judges, not following the scoring criteria, but everything we have imagined on the first day we started the project. Those might not be so innovative or mind-blowing to seize the first prize, but those were the true “value” we want to give people, and I believed those were also what we were all proud of. And I presented almost perfectly (in my opinion only, and comparing to my past presentations) without having to write any notes.

I knew we might not win because we focused more on providing people the best experience with every current technology available at the current time, not creating some futuristic tech like many other participating projects. But I also strongly believed that we could win, if we could make the judges saw what we saw: we did not make the technology or the only app using the technology, we made the app using the technology in the most efficient and thoughtful way.

That was how we won the competition. That was how Saint Petersburg became a new milestone of my life!

Windows Store Protocol to check for app updates

If you have used a Nokia Lumia phone, you may already see how Nokia forces the users to update their apps. They put the blank page with a background image and an Update button right after the splash screen (if there is one); tapping the button will get you to the app’s detail page in Windows Phone Store and you can update the app directly there. On the developer side, to do the same thing, you just have to use the API exposed through MarketplaceDetailTask to jump to that detail page.

The situation seems to be more complicated on Windows 8 with the Windows Store. Unlike the Windows Phone Store, going to the app’s detail page in Windows Store will not show you any update buttons. Instead, you will have to go to Settings charm of the Store, choose App updates and tap on Check for updates. How to do all these steps programmatically from your app (to help your users to quickly update the app)?

I had thought about showing a screen with screenshots telling people to do all the above steps by themselves, but it seemed to be too troublesome for the users. Then I saw an ads on Bing Sport app showing that there was an update in the Store, tapping on the ads jumped us directly to the Check for updates page, which is so nice and convenient! Therefore, I realized the Windows Store must already handle some special kinds of protocols or URL formats for that, and after some times trying, I figured out the magic words:

ms-windows-store:updates

Basically, you will just have to call that URL by a Launcher and the Store will start checking for app’s updates immediately!

Update: I have also checked that URL in Windows 8.1 and can confirm that it still works in the new Store.

DEP0700: Registration of the app failed. Another user has already installed a packaged version of this app.

If you are developing Windows Store apps and you have multiple accounts on your laptops or PCs, you may be familiar with this problem. This happens when you try to install or deploy an app on your testing devices when the app is already deployed (by Visual Studio or PowerShell) on another user account. You will have to log in to that account to remove this app first. Sound troublesome, at least it works.

But what if you have just removed that problematic user account without uninstalling the app beforehand? I got into that weird situation when I try to test Project Timeline on a new testing account and delete the old one: I could neither deploy the app (even install from the Store) nor uninstall from the deleted user account.

Wandering around the internet, I saw several suggestions to solve this. One of them was to simply change the family name, which was not very convenient for me since I wanted to test the IAPs as well. Trying different other suggestions, I finally found a good solution: just remove the PackageRepository.edb file, and everything worked normally again. You could read the details in this blog post:

http://blog.falafel.com/Blogs/JonathanTower/j-tower/2013/04/04/fixing-windows-8-deployment-error-error-dep0700-registration-of-the-app-failed-

I have also come up with another solution which does not actually solve my problem but provide a way to remove all the deployed apps quickly.

http://stackoverflow.com/questions/13865930/how-to-uninstall-an-app-that-another-user-installed

Update: I have a problem now. After a while, all the Windows Store apps (except IE) on my tablet stop working: they stopped showing up when I tapped their tiles and the event viewer showed problem with their license. I am still not sure if removing the PackageRepository.edb caused the problem or my messing around earlier did. I have tried to remove the developer license, reinstall it again, remove old user accounts, add new ones, and some others, but only Store app and newly installed apps were working then. I finally have to refresh the devices. Luckily, the problem was then solved and all the Windows Store apps were keep intact.

What we have learnt during the development of Speak Reminder and Group Tiles

So it’s been a while since we published Group Tiles and Speak Reminder to the Windows Phone Store. In case you did not know, Group Tiles is an app to create header tiles on the Start Screen to separate your messy tiles into distinguishable parts, and Speak Reminder is an app leveraging the Voice commands functions of Windows Phone 8 to help you create quick reminders.

You can download the 2 by scanning or clicking on the 2 QR code below:

Group Tiles

Speak Reminder

 

We did get a significant number of users of those apps, around 30 thousands for Group Tiles and 3 thousands for Speak Reminder. That is great not just because of all the encouragement and opportunity of that user base, but our users also help us to identify so many small bugs that were not stated on the Windows Phone Dev Center.

Group Tiles

Ok I will start with this guy first. This was really a big success for us. First day, we have 16 downloads, rather in line with our previous apps on Windows Phone, but then second day, we have more than 600. We were so amazed by the number and then shocked on the day this app was featured on WMPowerUser, almost 3000 in a single day.

Unfortunately, we did not prepare for that “success”. Our host provider constantly complained us abusing the shared server and suspended our account. We then realized the problem in our telemetry service (yes, I build one for our app instead of using an existing service like flurry to get more control and also to learn more about those kinds of problems). Somehow it went crazy consuming all the CPU resources, even though only a simple insert command is execute with the entity framework.

Back at that time I was so naïve and write the very “simple” lines as below to insert an information log to a project:

info.Project = project;
project.Infoes.Add(info);
context.Infoes.Add(info);
context.SaveChanges();

What could go wrong anyway? The first 2 lines were for the association between the 2 entities. The third line were to add that new info entity to the database and the last were to save all changes. I then had to profile each line of my code (there some other processing as well) to find the culprit, and it turned out to be the second line was not only unnecessary but also very dangerous:

project.Infoes.Add(info);

Instead of just marking the association, this would query all the info records of this particular project (which is around 10,000 at that time) every time a new one was inserted (at a crazy rate of around 1 time per second). Removing that line and everything worked exactly as expected.

We then moved all the telemetry modules to Azure Web Sites and SQL Azure, and were very happy with what those 2 provided, including very useful monitoring information on the dashboard.

So there were also two other small bugs that was detected by our users, one are very easy to identify and the other are more difficult to identify and fix.

IOException & IsolatedStorageException

This one was so straight forward although I doubt not many apps check for that. The app simply could not save the tile images when there is not enough space on the phone, and it could not save any settings as well, so be careful of this case if you put something important into the isolated settings.

ArgumentException – XcpImports

This was the full stack of that exception:

at MS.Internal.XcpImports.CheckHResult(UInt32 hr)
at MS.Internal.XcpImports.SetValue(IManagedPeerBase obj, DependencyProperty property, DependencyObject doh)
at MS.Internal.XcpImports.SetValue(IManagedPeerBase doh, DependencyProperty property, Object obj)
at System.Windows.DependencyObject.SetObjectValueToCore(DependencyProperty dp, Object value)
at System.Windows.DependencyObject.SetEffectiveValue(DependencyProperty property, EffectiveValueEntry& newEntry, Object newValue)
at System.Windows.DependencyObject.UpdateEffectiveValue(DependencyProperty property, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, ValueOperation operation)
at System.Windows.DependencyObject.SetValueInternal(DependencyProperty dp, Object value, Boolean allowReadOnlySet)
at Microsoft.Phone.Controls.PhoneApplicationFrame.System.Windows.Controls.IFrame.set_Content(Object )
at System.Windows.Navigation.NavigationService.CompleteNavigation(DependencyObject content, NavigationMode mode)
at System.Windows.Navigation.NavigationService.<>c__DisplayClass7.b__4()

There was not much information inside the exception to identify what had caused the crash. It happened in all our apps and we could not reproduce the problem at all.

I left it there for a while until I suddenly reproduced the crashes with the same exception: we navigated to a page inside the OnNavigatedTo function of another page, which sometimes caused both page to appear (one just overlay on the other), then the app would crash if the user press back button. The problem was slightly overcame by putting the navigation inside Loaded event handler instead, and now the crash rarely occurs.

Speak Reminder

We were very careful in implementing with the new speech feature of Windows Phone. There is a post here http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj662934(v=vs.105).aspx stating how to handle speech error. However, they only handle the function call, which is definitely not enough.

There are 2 other places that you will have to wrap with try catch block. The first one is the SpeechRecognizer, SpeechRecognizerUI and SpeechSynthesizer constructors, and the second one is the function call to register the VCD file with the system. Below are the exceptions that we have met in Speak Reminder

Exception (Exception from HRESULT: 0x800455BC) – SpeechRecognizer, SpeechRecognizerUI, SpeechSynthesizer constructors

    at Windows.Phone.Speech.Recognition.SpeechRecognizerUI..ctor()

As the documentation on Dev Center, this error code means “The requested language is not supported.” And this will happen on a new phone (or sometimes after you reset the phone) when the speech is activated, a language is chosen, but the language pack is not actually downloaded and installed on the phone. The user will have to go to phone settings to choose another speech language and then switch back again to see the message prompt for installing the language pack.

ArgumentException (Value does not fall within the expected range.) – SpeechRecognizer, SpeechRecognizerUI, SpeechSynthesizer constructor

    at Windows.Phone.Speech.Recognition.SpeechRecognizerUI..ctor()

This one is rather strange and is not documented on Dev Center. This also happens on new phone; sometimes there is no selected speech language. The user just have to choose one and this should be ok.

FileNotFoundException (The system cannot find the file specified. (Exception from HRESULT: 0x80070002)) – InstallCommandSetsFromFileAsync

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()

This one is very strange and I have not found the exact reason or solution for this. Would be very grateful if someone can tell me how to handle this case (except from silencing the error or just show a useless error message). I found something about missing XML files on some phones, but I am not too sure about that.

DirectoryNotFoundException (The system cannot find the path specified. (Exception from HRESULT: 0x80070003)) – InstallCommandSetsFromFileAsync

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()

This one is the same as the above.

Conclusion

It is a great opportunity for me to improve my skills when there is that large number of users, and I am very happy about that. On other lesson that I have learnt about Windows Phone Dev Center is that the automatic crash reports of the system usually lack of information (for example inner exception or stack trace), so you should try to report it yourself.

Windows Store certification, and Privacy Policy again

I think I have seen many different posts on this already. People keeps reminding others about putting a Privacy Policy page if you app happens to connect to the Internet.

I already have a published app on the Store, and this time is my second one. I always remember about the requirements so I put a setting for Privacy Policy right from the beginning and linked it to a page on the app website. The problem was I had not implemented the webpage at all. The situation at that time forced me to publish the app rather early, so I decided to put the website later, after I had submitted the app, when the certification was going on.

Pushing the website back was a good idea and it helped me to finish the app on time, but it turned out to be not a totally good. One may suggest that I should have put a basic page for the Privacy Policy and delayed the rest, but the problem was more complex than that. There were actually 3 pages that need to be implemented for the certification: the Privacy Policy of course, the How To page (I included this setting as well, thinking that this could help me to put work later, even after the app is published on the Store), and surprisingly the home page as well (I put a link to the home page inside the About settings). The home page surprised me because I thought I already have it there, but then I realize the testers also rejected the current blank home page (with a default Index header on top); this was regards as incomplete functionality of the app.

So next time I will have to note down every link I have inside the app, making sure that I do not forget any of them before a Microsoft tester starts to fail the app!

And I would say, this is painful.