Why Universal Apps as not as universal as you may think

I have been developing Windows Phone apps for a few years now, always sticking to Silverlight and keeping using Silverlight also after Microsoft announced the WinRT flavor of Windows Phone apps and the so called Universal Apps. The Windows Phone 8.0 and 8.1 Silverlight APIs have some limitations, but are now well known do not contain many bugs. They are the safe choice if you want to create a Windows Phone apps. And do not forget that there are still many device running Windows Phone 8 (like Verizon customers in the US) that never got the 8.1 updated promised to everyone during the summer.

Really universal?

Windows Phone 8.1 XAML and Universal Apps included WinRT APIs that have many problems, including some that there is no solution for. But first, let us just talk about the “Universal Apps” name. I think it is quite arrogant, calling universal something that targets two platforms, that frankly not so many users use or care about. Also if you only think about the Windows platforms, these apps are also not universal, because they cannot target the most commonly used Windows versions (7 and XP). But I am digressing.

I used the WinRT APIs when creating first Windows 8 apps about 2 years ago, so I am not new to the APIs. I have not touched the WinRT APIs again until recently, because there was no demand for Windows 8 or Windows 8.1 apps. Why would it? People use Windows 8 or 8.1 but do not care about Metro apps, they give them no value compared to “normal” Win32 and Windows tablets are practically non-exists (expect for the Surface tablets owned by few programmers and maybe no one else).

Universal Apps

Recently, a client was thinking about adding a Windows Phone app for their service the its existing Android and iOS apps, but they did not think it was worth the money. So the local Microsoft branch told them they would pay for the app (seems like many of the app here are created this way) under two conditions. The app had to be a Universal App and had to be finished before the years end. The client agreed and I had to create a Universal App. And the problems started.

In theory, Universal Apps are supposed to make code sharing between Windows Phone and Windows 8.1 simple and allow you to reuse as much code as possible. This works on the trivial Microsoft samples, but try to create a real world app. I have a business logic project with API calls, storage, etc. in a portable class library (like I always did before Universal Apps existed) and I created an Universal App from the template. And the #ifdef hell started.

#ifdefs everywhere

With Universal Apps you can safely share the ViewModels (I am using Caliburn.Micro) .. and that is about it. You have to create separate Views (because on phone and desktop information is typically displayed different), but the worst parts are the #ifdefs.

You need to set some properties of the main Frame, you have to use #ifdefs because the frame is a bit different on phone and desktop (like animations). You want to reuse as much DataTemplates as possible, so add another #ifdef for adding the right resource dictionary or many #ifdefs in the data templates to tune them, because it does not matter you use GridView on phone and GridView on desktop, they behave a bit differently in some cases.

Then you need to add audio playback to your app. There is a background audio playback API for Windows Phone 8.1 and none for Windows 8.1 In Windows 8.1 you need a global MediaElement in your Frame and handling everything differently. So add another big #ifdef. And by the way, the background audio playback API for Windows Phone 8.1 really sucks compared to the old Silverlight APIs. Just try downloading the sample form MSDN and hitting Suspend and Resume in Visual Studio, the background agent crashes horribly, without any exception and takes your Visual Studio instance to hell with it. And of course, the background audio playback API does not work on some phones. Just does not work. I confirmed this finding with other developers. Another messed up API that used to work before the whole Universal Apps hype. And explain this to the client who sees that things like this work on iOS, work on Android, hell, they even for on Windows Phone 8.0 (Slivelight) apps.

More messed up APIs

So background audio playback API for Windows Phone 8.1 is messed up, anything else? Sure. BackgroundDownloader is another example. In Silverlight, there was a BackgroundDownloader that was quite limited, but it worked. In Universal Apps, there is a new BackgroundDownloader with some new features, and some essential ones missing. For example, in Silverlight, each download could have a Tag, where you can store any data so you know something about the download when it finishes (to what business entity it belongs, etc.). Not any more in Universal Apps. There is no Tag, so you have to build and manage you own kind of index for all the downloads, so you can actually match them to your business entities. An annoyance, but nothing you cannot manage, right.

The BackgroundDownloader in Universal Apps has a bigger problem. It sometimes crashes so horribly, that it reboots the whole device! No exception, no logs, just a reboot. The maximum limit for the BackgroundDownloader is 1000 downloads, but try adding say 300 to the queue, cancelling them after a few minutes (does not seem to matter if you use one cancellation token or give each download its own) and there is a good chance the phone or the emulator will reboot itself. Not always, but quite often. Again, try explaining this issue to the client.

Performance

In Silverlight, I commonly used the LongListSelector to display data, using it with a WrapPanel when I needed to create a two column layout. The LongListSelector is gone, in Universal Apps you have to use GridView also on Windows Phone. Or you can use the ListView with a custom wrap panel you write yourself or download somewhere, but it takes some effort to make it do virtualization properly.

So you use GridView on both Windows Phone 8.1 and Windows 8.1 to make it consistent. Add tens f of items with images to it and the performance starts to really suffer. Gray placeholders will show up and more importantly, never disappears. You do not event need images, just add about 300 text only items to the GridView and the gray placeholders will starts to show when scrolling.

Need another proof that the WinRT controls are slower? Just take a look at this video comparing the media app on and old Windows Phone 7 to the media app on a much more powerful device running Windows Phone 8.1. You can see that the old, single core device runs the Silverlight apps faster than the new powerful phone runs the new WinRT equivalent of the app.

REST service base class for Windows Phone 8.1 XAML apps

Communicating with a JSON based REST service is a task that many Windows Phone apps have to do. My apps sure do it a lot so I came up with a base class that I use in all of them, put it on Github and created a Nuget package, so your apps could use it to.

The usage of this base class is simple. Create your service class and inherit from BaseRestService. The minimum you need to do to make it work is to override the GetBaseUrl() method to set the base url for all the requests. If youu need and the GetRequestHeaders() to set the default request headers.

and you can now use the following protected methods

All the JSON serialization and deserialization is automatically done for you. If you need to execute some action before every request (like checking if the OAuth token expired and refreshing it), simply override the OnBeforeRequest() method.

Methods in your service may then look like this

In case of an error, the methods throw either a DeserialziationException with the original data if deserialization failed, or a ConnectionException with the HTTP status code.

if you need some additional features, just raise an issue in the Github repo, or create a pull request.

Visual Studio template for Caliburn.Micro Windows Phone apps

I have been building Windows Phone apps using the Caliburn.Micro framework for some time now. Setting up a new project takes some time and can be easily automated, so I decided to create a Visual Studio template for Windows Phone apps build with Caliburn.Micro.

The templates can be downloaded from the Visual Studio Extensions gallery and used to build Windows Phone 8 and Windows Phone 8.1 Silverlight apps. It contains the basic setup with Caliburn Micro and Fody, with a sample view and viewmodel.

The source code is available on GitHub, so if you want to modify it to best suit your needs, feel free to do it.

Detecting tablets and smartphones in ASP.NET

I recently worked on an ASP.NET application that needed to detect if users were coming from tablets or smartphones. The project used data from http://user-agent-string.info/ to do this detection, but the result were not really good. We needed a better solution, so I came up with using WURFL.

WURFL, the Wireless Universal Resource FiLe, is a Device Description Repository (DDR), i.e. a software component that maps HTTP Request headers to the profile of the HTTP client (Desktop, Mobile Device, Tablet, etc.) that issued the request. Adding WURFL to your ASP.NET application is easy thanks to the WURFL_Official_API Nuget package. The Nuget package also contains definition file, so you just need to update the Nuget package once in a while to get your definition file up to date.

After installing the Nuget package, you need to setup WURLF in your Global.asax file

I recommend setting the match mode to accuracy instead of speed, to get the best results. Using the WURFL library is also quite easy, just pass the user agent string and get the properties you want.

TvTime: track your favorite TV shows on Windows Phone

We have just had released a new app called TvTime. TvTime is a simple and beautiful app for tracking your favorite TV Shows. Simply add a find the TV Shows you like, add them to the list and get detailed information about actors, air times and episodes. If you decide to track unwatched episodes, you will always know what you have already seen. So get TvTime now so you never miss your favorite TV Show!

Main features

  • clean and simple design
  • thousands of TV Shows to choose
  • tracking unwatched episodes
  • live tile
  • show and episodes details

You can download the app for free here.

What to put on the about screen of your Windows Phone app

The about screen of a Windows Phone app is usually the most overlooked part of the app. Sure, the users usually visit it only once, after installing the app, if ever, but it is a part of your Windows Phone app that you could put to a good use.

If you have ever taken a DVLUP challenge you may have noticed, that they recommend you place a text describing your app on the about screen. I really do not agree with this. If users install your app, they know what the app does and if they cannot figure it out, then your UI is a failure and the about screen will not save you.

After some trial and error I came up with a standardized about screen I now use in all my apps. It is a pivot with two tabs; About and More apps.

The About tab is the most important. It shows the version of the app, this is important when users report problems, information about the author and the designer of the app with Twitter contacts and buttons to send feedback via email and rate the app in the Windows Phone Store. Providing a feedback mechanism is really important, the users will write you about an issue they have with the app instead of just giving you a bad review in the Windows Phone Store.

The screenshot shows the About page from my latest app TvTime. You can easily get the app version from the manifest using the ManifestHelper from the Kulman.WP8 Nuget package.

You should know that submitting an app is just a beginning, you then have to answer to user feedback, provide bug fixes, etc. In my case, the Feedback button launches an EmailComposeTask with filled in recipient and subject so the users just write what is on their minds and send it to me. I always answer each and every one of those feedback emails.

I use the second tab, More apps, as a form of cross-promotion.

If the users like your app, they may also like your other apps so why not make it easier for them to get them. I have a simple XML file with names, links and icons of my apps hosted on a webserver that the app downloads and displays, of course removing itself from the list.

To sum it all up, do not underestimate your about screen, use it to provide your users with a feedback mechanism. You will make your apps better.

Experience with being featured in the Red Stripe Deal promotion on Windows Phone

I was offered to to take part in the Red Stripe Deal promotion on Windows Phone with my Shopping List Simple app from 21st August to 28th August.

In this promotion, your app has to cost less than half of the normal price. The app normally costs 1.29 USD in most countries and 0.99 USD in Czech Republic, Slovakia and Russia to boost the sales. The minimum price in Windows Phone Store is 0.99 USD so the app had to be made free for the promotion. So I filled in the form saying that I want my app to be free in all the countries during the promotion. When the time of the promotion came, the price was set to free in all the countries except Czech Republic, Slovakia and Russia. First day, first problem.

Positives

The promotion was a success with about 25 000 (free) downloads.

Another positive effect was that I got contacted by users offering translations of the app and acquired Turkish and Ukrainian translations.

Negatives

As soon as the Red Stripe Deal promotion ended, I submitted a new version of the app with the two new translations … and the problems started. The users started to report that the update fails to install, usually with 80004005 as the error code. If you try to google this code, you find out it is too generic, ranging from Zune to XBOX and that no helpful info can be found about this error code.

I contacted Microsoft support and they, as usual, were not helpful at all. They replied that everything is ok with the app, the error code indicates WiFi issues, so it is a problem on the users’ end and that they should contact the support.

There was another problem. Users who got the app for free thanks to the Red Stripe Deal and uninstalled it, had to pay for when reinstalling. This really sucks and I am sure that in the past, when you got an app while it was free you never had to pay for it in the future. It looks like things changed, because I got this from Microsoft:

In regards to users having to pay for the app if they re-install it, this works as designed. If the app was free when it was downloaded and the price changes between the time the consumer re-installs they will be charged whatever the “New” price is.

Looks like this was an misinformation from Microsoft, they corrected it:

Let me correct myself. The only time I see the app being changed is when I use a device that is not tied to the live Id that I purchased it from. If I buy an app under myself@live.com and then login to another device using a different live Id I will have to pay for the app. If I use the same live Id I own the app and will not have to pay even if the price of the app has changed. You will also see a change for the app if I have loaded the app on the maximum number of devices allowed.

The other error code, that the users were experiencing, was c101a7d1. Microsoft support sent my a link to a discussion suggesting users uninstall the app and install it again, meaning they would have to pay for it now (according to users who tried it), maybe all 25 000 of them! This is going to be a real blow to the reviews and ratings! And some people even thing I did it intentionally to make money!

Conclusion

So what did the Red Stripe Deal bring me? Many new users, but many of them angry about the update problems and need to buy the app when they uninstall it and it also made some of the “old” users angry about the update problem. Was it worth it?

Update: Problem still not solved.

I told the users to contact Microsoft support as Microsoft support told me, but they report the support cannot / will not help them. The support guy I am in contact with did not want to believe this, so I had to ask one user for a screenshot of Microsoft support telling him they cannot help and send it to him. Did not help either.

Automatic ViewModels and Services registration for (not only) Caliburn.Micro

My MVVM framework of choice, Caliburn.Micro, provides a simple Dependency Injection container, where you have to register all your ViewModels and Services. This is done in the Bootstraper’s Configure method and may look like this:

where you typically register your ViewModels as per request and services as singletons.

Of course this is done just once, but having to register a ViewModel each time you create a new one can be a nuisance, especially in a large project.

There is a better way that uses reflection. First, you need to create attributes that will represent registration as per request and a s singleton:

Iterating over all the non-abstract classes in your assemblies using reflection is quite easy, the tricky part is deciding when to register a class as “itself” and when to register it for an interface it implements. My rule of thumbs is that if the class implements exactly one interface, it is one of my services and I register it for that interface, otherwise I register it as itself (ViewModels descendant from Screen implement circa 5 interfaces).

The final registration code looks different for WinRT (Windows 8, Windows 8.1, Windows Phone 8.1 XAML)

and for “classic” .NET (Windows Phone 8)

because of reflection differences in WinRT. Do not forget to add the PerRequest or Singleton attribute to your classes to make it work.

Converting between pixels, meters and map coordinates in Windows Phone

In my current project I needed to solve one quite interesting problem. Imagine you have a map with some pins representing points of interest. If the user taps on a pin, a label with the place title is shown like on this image (that is not from the real project, obviously).

Map

The client had an interesting requirement. When the user taps the pin and the label is shown, they wanted the label to be centered on the map (basically move the map so the label appears in the middle of the map).

In Windows Phone you can only center the map to a GeoCoordinate. If you center the map to the tapped pin’s coordinate, it is not quite right, you also need to move it by half the width of the label to the left (and half of the height down). So the solution consists of two steps

  1. Convert half of the label width in pixels to meters for a given zoom level (pixels -> meters conversion)
  2. Subtract the result from the pin’s coordinate (meters -> degrees conversion)

(and the same for height)

The map component in Windows Phone 8 and 8.1 has quite a nice documentation, so the first step requires some math but is not so difficult.

I created two helper functions to take care of this first conversion

The second conversion is more difficult, especially if you want to do it really well. I found a simple solution that works quite ok when you are not right at the poles and used it. The helper function looks like this.

Now you just need to put it all together and you are done.

Ignoring certificate errors in Windows Phone 8.1

Connecting to servers with self-signed, expired or otherwise problematic certificates has always been a problem in Windows Phone. There is no way to ignore certificate errors in Windows Phone 7 and Windows Phone 8, not even using the new Portable HTTP Client Libraries. If you are dealing with a self-signed certificate on the server, you have to somehow get it (may not always be possible) and install it on the device or in the emulator (for emulator every time you close and start it again). Ignoring certificate errors would be a much more comfortable approach. Of course, only do it in development with dev servers, not in production.

In Windows Phone 8.1 there are strangely two HttpClient classes, one in System.Net.Http and another in Windows.Web.Http. Normally you would go with the one in System.Net.Http because you are probably using it thanks to the mentioned Portable HTTP Client Libraries on every other platform. You are out of luck in Windows Phone 8.1 XAML, if you want to ignore certificate errors, you have to use the one from Windows.Web.Http, because only this one accepts an IHttpFilter as an argument.

Using the IHttpFilter, you can easily ignore certificate errors

but you have to get used to doing all the request in a different way, the Windows.Web.Http.HttpClient way that differs from the System.Net.Http.HttpClient way.

© 2014 Coding Journal

Theme by Anders NorenUp ↑