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.
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).
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
- Convert half of the label width in pixels to meters for a given zoom level (pixels -> meters conversion)
- 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.
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.
Windows Phone 8.1 introduced many interesting new thing, the one I personally like the best as a developer is the Share Contract. The Share Contract allows your apps to share data using an unified and easy way and also to receive data from other apps. This functionality is important for my Pock8 app, which is a Pocket client. By making Pock8 app a Share Contract target, the app can receive links from other apps, more importantly from the built-in webrowser (IE). This makes the app even more easy to use and valuable.
The problem is that all the documentation I found and also the sample app are for Windows Runtime. Pock8 is a Silverligt app and I have no intentions to rewrite it to Windows Runtime.
I had to make some digging and I finally found the solution in a build video called Contracts and Pickers: Building Apps that Work Together on Windows.
First you have to add the Share Contract ability to the new manifest file (Package.appxmanifest, the Declarations tab). If you want to receive links, Choose weblink as data format. This step is the same for Windows Runtime and for Silverlight apps, but all the other steps differ.
You can determine if your application was launched normally or as a Share Contract target in the application Launching event. If you cast the LaunchingEventArgs to ShareLaunchingEventArgs and the result is not null, your application was launched as a Share Contract target. The video recommend creating an internal property of type ShareOperation in App.xaml.cs and saving the data from ShareLaunchingEventArgs there:
(I use Caliburn.Micro so I do it in the OnLaunch method of the Bootstrapper)
The next thing to do is to show a separate sharing page instead of the page you would normally show when your app starts. Create a AssociationUriMapper like you would do when registering for a protocol and simply check the ShareOperation property in App.xaml.cs:
If you use Caliburn.Micro as I do, do not forget to register the AssociationUriMapper in the Boostrappers CreatePhoneApplicationFrame method:
Some time ago I needed a way to programatically search the Apple AppStore and Google Play Store to get some info about apps for a project. I decided to write an F# script for that task and later added support for Windows Phone Store.
I wanted the script to be easily usable from outside of F# so first I created a type for the app.
I also needed a helper function to download data from the web. I used a classic WebClient with user agent set to Chrome, because the Windows Phone Store API requires a user agent header
Searching in Apple AppStore is easy, because Apple provides a simple search API that returns JSON. Thanks to the JsonProvider from FSharp.Data, the code is really simple
Just downloading the JSON transforming the data to our type.
Google Play Store
Searching in Google Play Store is a bit more of a challenge. There is no API I could found so I had to parse the html returned from the web version of Google Play Store. The web can change at any time so I need to be aware of this fact and fix the method if it happens.
Another problem with parsing the web is that there is no way to return search result for a specific country like for Apple AppStore. The web always shows results according to your IP address.
Windows Phone Store
There is no official API for searching the Windows Phone Store but I was given a tip obtained after sniffing the traffic from a Windows Phone, so I did not have to parse the web. The code is as simple as for Apple AppStore thanks to XmlProvider.
Using F# is fun and processing data is really simple thanks to type provides. You can find it whole code at https://github.com/igorkulman/AppStoreCrawler.
FAKE is a build automation system with capabilities which are similar to make and rake. It is using an easy domain-specific language (DSL) so that you can start using it without learning F#. If you need more than the default functionality you can either write F# or simply reference .NET assemblies.
I have been using FAKE for quite some time now on some fairly complex projects for not only building but also running tests and creating and pushing Nuget packages and I really like. I decided to add FAKE build scripts to my Windows Phone apps to make the process of generating a XAP file for the Windows Phone Store easier.
The FAKE script I use can by used with any Windows Phone app, it will build all the projects and copy the XAP file to a release directory.
To get the script started, you need a batch file
and Nuget.exe in tools\NuGet directory.
If you create an Windows Phone 8 app and test it only on WVGA and 720p devices or emulators, you may be surprised how you app looks on a WXGA device (or emulator).
I have not been able the reason why this happens but the solution is quite simple. Set your page’s top border to -1.
Doing this in XAML for every page is not very convenient, a better solution would be to set the negative top margin on the whole application frame
If you use Caliburn.Micro, you need to override the CreatePhoneApplicationFrame in the Bootstrapper instead
Getting contacts info on Windows Phone means using a callback based API provided by the Windows Phone SDK
I really dislike all the callback-based API so I was looking for a way to convert it to an async/await based API. And it is quite easy to do so
You can find this implementation in my Kulman.WP8 library (also available on Nuget)
Windows Phone Store does not offer developers any sandbox to test in-app purchases in their apps, like stores on other platforms do. If you want test in-app purchases in your Windows Phone apps, you need to use other options.
To make in-app purchases implementation easier, I created a simple Windows Phone Store service interface in my Kulman.WP8 library (also available on Nuget)
If you publish your app as a private beta and add the in-app products, you can test them. All the in-app purchases are always free in this scenario. The disadvantage is that you cannot debug anything, it either works or it does not (if you use my implementation from Kulman.WP8, it should :).
Real app testing
If your app is already in the Windows Phone Store, create an in-app product and try to buy it from your app run from Visual Studio, you may be wondering, why you are getting an error. The problem is that the app run from Visual Studio has a different app id from the app in Windows Phone Store. If you change the app id in the manifest to the app id state in Windows Phone Store (the details view), you will be able to make a real in-app purchase.
To mock in-app purchases you can use the Mock In-App Purchase Library. To make testing easier, implement my interface using this library
And setup the products you want to use at your app startup
The advantage of this approach is that you just switch the IWindowsStoreService implementation between then mock on and the real one, depending on the situation. For example (Caliburn.Micro Bootstrapper)
Recently I have released a new Windows Phone app called Pock8. Pock8 is a beautiful Pocket (formerly Read It Later) client for Windows Phone. The design of the app was created by Jan Marek who worked with my on the Shopping List Simple app.
Our goal was to create a Pocket client that would be really easy to use and that would have a nice and simple design. I think we have achieved our goal. The main features of the app are
- clean and simple design
- optimized article view for comfortable reading
- article cache for offline reading
- dark theme for OLED screens or reading in the dark
- support for receiving articles from other apps like WPCentral
- listening to articles aloud
- sharing articles
In version 1.2 we really concentrated on user feedback and added many features that our users requested. We love and users and want to make them happy.
The app is free to use with one limitation, all the list display just 5 articles at any time. You can use an in-app purchase to get rid of the limitation and support further development of the app.
For more info about Pock8, follow the app on Twitter at @pock8app.