Nico's digital footprint

I grew up in the nineties, that makes me awesome by default

Launching a Win8 app from WP8 with Azure custom API

by Nico

Imagine you have an app where people can browse through all sorts of data, let’s take Wikipedia for example. You find an interesting article on the Wikipedia app on your Windows Phone device. A phone screen is (usually) pretty small so it would be nice if we could just send that article to our pc where a toast pops up, when the toast is clicked the Wikipedia app on Windows 8 opens up on that same article. A nice experience for the user, added value for our apps and not too hard to do.

The Service

As the title of this post mentiones, we’re going to use Windows Azure Mobile Services for this. A while ago Microsoft launched the custom API option in Mobile Services (WAMS for short) and those custom APIs are just what we need.

The server side of WAMS uses Node.js so that means:

We’ll start by creating a new Mobile Service (if you don’t know how, follow this tutorial to the point where they’re creating a new app, we’ll create the app manually).

Once the mobile service is created, navigate to the API tab and add a new API. Gave it a name and leave the permissions default. The end result should look like this.

Click the arrow icon next to the API name to start editing the script. The script looks like this by default.

Code Snippet
  1. exports.post = function (request, response) {
  2.     // Use "request.service" to access features of your mobile service, e.g.:
  3.     //   var tables = request.service.tables;
  4.     //   var push = request.service.push;
  5.  
  6.     response.send(statusCodes.OK, { message: 'Hello World!' });
  7. };
  8.  
  9. exports.get = function (request, response) {
  10.     response.send(statusCodes.OK, { message: 'Hello World!' });
  11. };

There are options here both for POST and GET methods, implemented with Hello World stuff. We’ll only be needing the POST part, the GET method we’ll just leave alone.

This is the new POST method:

Code Snippet
  1. exports.post = function (request, response) {
  2.     process.env.WNS_CLIENT_ID = 'YOUR_CLIENT_ID_HERE';
  3.     process.env.WNS_CLIENT_SECRET = 'YOUR_CLIENT_SECRET_HERE';
  4.  
  5.     var wns = request.service.push.wns;
  6.     var message = request.body.message;
  7.     var title = request.body.title;
  8.     var launchParam = request.body.launchParam;
  9.     var channel = request.body.channel;
  10.  
  11.     wns.sendToastText02(channel, {
  12.         text1: title,
  13.         text2: message
  14.     },
  15.          {
  16.              launch: launchParam,
  17.              success: function () {
  18.                  response.send(statusCodes.OK, { isSuccess: true, response: statusCodes.OK });
  19.              },
  20.              error: function () {
  21.                  response.send(statusCodes.OK, { isSuccess: false, response: statusCodes.NOK });
  22.              }
  23.          }
  24.          );
  25.  
  26. };

You’ll notice on line two and three that you’ll need to insert your own client ID and client secret. To get those we’ll need to create a new app on the Windows Store developer site.

Give an app name to the new app, save it and open the Services option.

On the services page, click on “Live Services Site”, on that site select “Authenticating your Service” and take note of the Client ID and Client Secret.

Usually, when using push notifications from a WAMS we can add those two keys into the management portal on Azure. However, when using a Custom API the WNS (Windows Notification Service) doesn’t seem to know that they are there. That’s the reason we’re including them into the script code here on lines two and three.

Last step here is to create a new Windows Store application in Visual Studio, Right-click the project, select Store and associate it with the app we’ve just created on the Windows Developer portal.

We now have an application hooked up to a registered application on the Windows Developer portal with access to WNS through the client ID and secret.

Let’s have a look at the rest of the script.

Code Snippet
  1. var wns = request.service.push.wns;
  2. var message = request.body.message;
  3. var title = request.body.title;
  4. var launchParam = request.body.launchParam;
  5. var channel = request.body.channel;

In the build-in API of WAMS we have access to an object called push. Push has a reference to WNS and can call push notifications. In a custom API we can find the Push object in request.service. Message and Title will be the content of the toast, channel is the channel used to send the toast from the server to the client and launchParam is what will determine the page we navigate to when the toast is clicked. All these parameters will be send over the wire from the Windows Phone app.

Code Snippet
  1. wns.sendToastText02(channel, {
  2.     text1: title,
  3.     text2: message
  4. },
  5.      {
  6.          launch: launchParam,
  7.          success: function () {
  8.              response.send(statusCodes.OK, { isSuccess: true, response: statusCodes.OK });
  9.          },
  10.          error: function () {
  11.              response.send(statusCodes.OK, { isSuccess: false, response: statusCodes.NOK });
  12.          }
  13.      }
  14.      );

This piece of the script will do the actual sending of the push notification. We call the sendToastText02 method on the wns object (for an overview of all the possibilities of wns, have a look at MSDN). The parameters for the method are simple, first it needs the channel. The channel is a direct link between an installation of your app and the server. It’s unique for every installation of the app. Next parameter is the payload of the toast, the information that will be shown on the toast message itself. Third parameter are the options. This is where we pass the launch parameters for the Windows app and the functions for success and error.

That’s all for the script. Pretty easy right?

Windows Phone app

The Windows Phone app is pretty straightforward as well. In this proof of concept it’ll just be an app with a bunch of buttons, when the Windows 8 app starts it will show the button that was clicked on the phone. Create a new Windows Phone 8.0 application and add the following NuGet package to the project.

Install-Package WindowsAzure.MobileServices

This will install the WAMS SDK into the project. We’ll need this SDK to fetch the channel and request the toast message.

The Windows Phone app only has one page with a really simple layout

Code Snippet
  1. <!--  ContentPanel - place additional content here  -->
  2. <StackPanel x:Name="ContentPanel"
  3.             Grid.Row="1"
  4.             Margin="12,0,12,0">
  5.     <TextBlock Text="Enter ID" />
  6.     <TextBox x:Name="TextBoxId" />
  7.     <Button Click="Button_Click" Content="Button 1" />
  8.     <Button Click="Button_Click" Content="Button 2" />
  9.     <Button Click="Button_Click" Content="Button 3" />
  10.     <Button Click="Button_Click" Content="Button 4" />
  11.     <Button Click="Button_Click" Content="Button 5" />
  12.     <Button Click="Button_Click" Content="Button 6" />
  13.     <Button Click="Button_Click" Content="Button 7" />
  14.     <Button Click="Button_Click" Content="Button 8" />
  15. </StackPanel>

A Textbox that will hold an ID and 8 buttons that use the same click event handler. The Windows 8 app that we’ll build in a minute will request a Channel from WNS, we’ll save that channel into our WAMS database. The ID that we enter here in the textbox is the ID of the record that holds the channel that we want to use. That means that in a real app, you’ll need to find a way to get the ID from the Windows 8 app into the Windows Phone app. Possibilities here are NFC or QR codes, or just plain text. Alternatively, you could use the username from a Microsoft Account to store and retrieve the channel instead of an ID.

Next we need to initialize the WAMS SDK in App.xaml.cs

Code Snippet
  1. public partial class App : Application
  2. {
  3.      public static MobileServiceClient MobileService = new MobileServiceClient(
  4.             "https://nicopushdemo.azure-mobile.net/",
  5.             "qCWCpYmWlJiOyXFQnKscFYnNixruku41"
  6.         );

You’ll need the values of your own service here of course. It can be found by going to the Azure management portal, selecting your WAMS and opening the “Connecting an existing application” option.

Here’s the button event handler for the eight buttons

Code Snippet
  1. private async void Button_Click(object sender, RoutedEventArgs e)
  2. {
  3.     Notification notification = new Notification();
  4.  
  5.     notification.Channel = await FetchChannel(int.Parse(TextBoxId.Text));
  6.     notification.Message = "Click to launch the app";
  7.     notification.Title = "Message from the Phone app!";
  8.     notification.LaunchParam = ((Button) sender).Content.ToString();
  9.  
  10.     var response = await App.MobileService.InvokeApiAsync<Notification, NotificationResult>("notifications", notification);
  11.  
  12.     if (response.IsSuccess)
  13.     {
  14.         MessageBox.Show("Toast succes!");
  15.     }
  16. }
  17.  
  18. private async Task<string> FetchChannel(int id)
  19. {
  20.     var channels = await App.MobileService.GetTable<Channel>().Where(c => c.Id == id).ToListAsync();
  21.  
  22.     return channels[0].ChannelUri;
  23. }

When one of the buttons is clicked an instance of Notification is created, Notification is a class that we build ourselves, looks like this

Code Snippet
  1. public class Notification
  2. {
  3.     [JsonProperty(propertyName: "message")]
  4.     public string Message { get; set; }
  5.  
  6.     [JsonProperty(propertyName: "title")]
  7.     public string Title { get; set; }
  8.  
  9.     [JsonProperty(propertyName: "channel")]
  10.     public string Channel { get; set; }
  11.  
  12.     [JsonProperty(propertyName: "launchParam")]
  13.     public string LaunchParam { get; set; }
  14. }

FetchChannel will use the entered ID to fetch the channel from the WAMS database (saving the channel in the DB will be done from the Windows Store app). The LaunchParam is the content from the button that was clicked.

Once the Notification instance is filled up, we call the custom API by calling InvokeAPIAsync, the generic types passed in are the type of the parameter and the type of the expected result. The expected result is NotificationResult

Code Snippet
  1. public class NotificationResult
  2. {
  3.     [JsonProperty(PropertyName = "isSuccess")]
  4.     public bool IsSuccess { get; set; }
  5.  
  6.     [JsonProperty(PropertyName = "response")]
  7.     public string Response { get; set; }
  8. }

The parameters for InvokeApiAsync are the name of the custom API, the object of the same type that was specified. The WAMS SDK will take care of deserializing that object into a JSON format using Json.NET before sending it over the wire to our API.

Windows 8 app

The final piece of the puzzle is the Windows 8 app. This is a very basic app consisting of two pages. An empty MainPage and a SecondPage. This to prove that you can navigate to any page when launched from a toast.

Create an empty Windows 8 app and once again add the WAMS SDK through NuGet.

Install-Package WindowsAzure.MobileServices

We’ll start by initializing the WAMS SDK in App.xaml.cs

Code Snippet
  1. sealed partial class App : Application
  2. {
  3.      public static PushNotificationChannel CurrentChannel { get; private set; }
  4.  
  5.      public static MobileServiceClient MobileService = new MobileServiceClient(
  6.              "https://nicopushdemo.azure-mobile.net/",
  7.              "qCWCpYmWlJiOyXFQnKscFYnNixruku41"
  8.          );
  9.  
  10.      private async void AcquirePushChannel()
  11.      {
  12.          CurrentChannel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
  13.          var settings = Windows.Storage.ApplicationData.Current.LocalSettings;
  14.  
  15.          if(settings.Values.ContainsKey("channel"))
  16.          {
  17.              string previousChannel = settings.Values["channel"].ToString();
  18.  
  19.              if(previousChannel == CurrentChannel.Uri)
  20.                  return;
  21.          }
  22.  
  23.          settings.Values["channel"] = CurrentChannel.Uri;
  24.  
  25.          await MobileService.GetTable<Channel>().InsertAsync(new Channel{ChannelUri = CurrentChannel.Uri});
  26.      }

A bit more initial work needed here. First the same codeblock as the one in the WP8 app. Next is the AcquirePushChannel method. This one will ask WNS for a push channel, save it to the WAMS DB and into the Application’s settings. This is because a channel has a lifetime, during this time the application will be able to reuse that same channel. On every app start we’ll check if the channel we receive from WNS is the same one that is stored in the WAMS DB, if it isn’t we store it again.

Now, the magic also happens here in App.xaml.cs, at the end of the OnLaunched method.

Code Snippet
  1. string launchArgs = e.Arguments.Trim().ToString();
  2. if (launchArgs != string.Empty)
  3. {
  4.     rootFrame.Navigate(typeof(SecondPage), launchArgs);
  5. }
  6.  
  7. // Ensure the current window is active
  8. Window.Current.Activate();

We’ll check to see if the LaunchActivedArgs have some arguments. If they don’t, nothing special happens and MainPage is loaded. If they do, the argument will be the LaunchParams we’ve passed from the WP8 app, to the custom API. That value has now finally reached our Windows 8 app via the toast. We navigate to SecondPage and pass in the launchArgs as parameter.

SecondPage.xaml looks like this

Code Snippet
  1. <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  2.     <TextBlock x:Name="SelectedItem" Style="{StaticResource HeaderTextBlockStyle}" />
  3. </Grid>

In the code behind of SecondPage we’ll need to override OnNavigatedTo

Code Snippet
  1. protected override void OnNavigatedTo(NavigationEventArgs e)
  2. {
  3.     SelectedItem.Text = "Navigated to this page by clicking in the phone app on " + e.Parameter;
  4.     base.OnNavigatedTo(e);
  5. }

And that’s basically it.

Making it happen

Run the Windows 8 app once, so that it’s installed on your system and a channel is registered and saved into the WAMS DB. Feel free to close the app afterwards.

Launch the Windows Phone app, insert the correct ID into the textbox and hit any of the buttons.

Click the toast when it pops up and be amazed by the result Glimlach

Conclusion

In this post I’ve talked about a way to share data between apps through the use of push notifications. When you have the same app on both Windows Phone and Windows 8 this provides a cool way for your user to switch platforms while remaining on the same part of the app.

Download the projects from my SkyDrive:


Tags:

.Net | Azure | Devices | NuGet | WP8 | WinRT | Windows 8 | XAML

LongListSelector with bindable SelectedItem

by Nico

In Windows Phone 8 Microsoft wants us to use the LongListSelector instead of the ListBox. But it seems they forgot about something, the SelectedItem property of the LongListSelector isn’t bindable. There are multiple work-arounds for this like event to command in XAML or setting the viewmodel property from the SelectionChanged event. That last one breaks your entire MVVM setup since the code behind of the view is now directly setting properties on the viewmodel.

Today I once again ran into this problem and decided to extend the LongListSelector to allow SelectedItem binding (note: I haven’t searched for an existing extended LongListSelector so it might as well exist somewhere else, this is just my attempt at it).

Create either a Windows Phone class library or a new class in a WP8 project, I called it ExtendedSelector and have it derive from LongListSelector, you’ll need to add a using statement for the Microsoft.Phone.Controls namespace.

Code Snippet
  1. public class ExtendedSelector : LongListSelector

First we’ll need a dependency property

Code Snippet
  1. public static readonly DependencyProperty SelectedItemProperty =
  2.     DependencyProperty.Register("SelectedItem", typeof (object), typeof (ExtendedSelector), new PropertyMetadata(default(object)));

and the property that is set through the DP

Code Snippet
  1. public new object SelectedItem
  2. {
  3.     get { return GetValue(SelectedItemProperty); }
  4.     set { SetValue(SelectedItemProperty, value); }
  5. }

Notice the “new” keyword on line 1? LongListSelector already has a SelectedItem property of type object, by using the new keyword we make the ExtendedSelector use our version of the property instead of the one from its base class

So now we have a property that can be bound to an object on our viewmodel, all there’s left to do now is set the actual selected item to the property. We do this by handling the SelectionChanged event, the event handler is hooked up in the constructor.

Code Snippet
  1. public ExtendedSelector()
  2. {
  3.     SelectionChanged += (sender, args) =>
  4.     {
  5.             SelectedItem = args.AddedItems[0];
  6.     };
  7. }

And that’s it, we now have a LongListSelector with a bindable SelectedItem property

Multi-select

Let’s take it a step further, we want to enable multi-selection of items in our ExtendedSelector.

Start by adding another dependency property

Code Snippet
  1. public static readonly DependencyProperty SelectionModeProperty =
  2.      DependencyProperty.Register("SelectionMode", typeof (SelectionMode), typeof (ExtendedSelector), new PropertyMetadata(default(SelectionMode)));
  3.  
  4. public SelectionMode SelectionMode
  5. {
  6.      get { return (SelectionMode) GetValue(SelectionModeProperty); }
  7.      set { SetValue(SelectionModeProperty, value); }
  8. }

SelectionMode is an enum containing three types of modes

  • Single
  • Multiple
  • Extended

I only need single and multiple, so I’m not going to do anything with Extended. Change the constructor of the ExtendedSelector to this

Code Snippet
  1. public ExtendedSelector()
  2. {
  3.     SelectionMode = SelectionMode.Single;
  4.  
  5.     SelectionChanged += (sender, args) =>
  6.     {
  7.         if(SelectionMode == SelectionMode.Single)
  8.             SelectedItem = args.AddedItems[0];
  9.         else if (SelectionMode == SelectionMode.Multiple)
  10.         {
  11.             if (SelectedItem == null)
  12.             {
  13.                 SelectedItem = new List<object>();
  14.             }
  15.  
  16.             foreach (var item in args.AddedItems)
  17.             {
  18.                 ((List<object>)SelectedItem).Add(item);                   
  19.             }
  20.  
  21.             foreach (var removedItem in args.RemovedItems)
  22.             {
  23.                 if (((List<object>) SelectedItem).Contains(removedItem))
  24.                 {
  25.                     ((List<object>) SelectedItem).Remove(removedItem);
  26.                 }
  27.             }
  28.         }
  29.     };
  30. }

When the class is instantiated we default the SelectionMode to Single, when the property is set from Xaml the setter fires after the constructor, so this is a safe place to put that. Next in the event handler we check for the SelectionMode, if it’s set to Single, nothing changes. When set to Multiple we check if SelectedItem already contains items, if it does add the newly selected item to the list, if it doesn’t we’ll instantiate SelectedItem first as a List<object>. If there are any deselected items we remove them from the list.

And that’s it. A problem easily solved. I’m just hoping that the product team will actually include this functionality in the next SDK update so this post becomes obsolete.

Conclusion

This post is a quick fix for the LongListSelector so it supports binding to SelectedItem. If you want the complete class, grab it on GitHub

Update

Scott Lovegrove pointed out that the Windows Phone toolkit (http://phone.codeplex.com/ ) has a LongListMultiSelector, allowing for multiple item selection. It still doesn't have a bindable SelectedItem property but it should be pretty easy to make one like I did with the normal LongListSelector it his post.


Tags:

.Net | WP8 | XAML

Don’t forget the system tray in your WP8 app

by Nico

The system tray in Windows Phone 8 is the small bar at the top where the clock, signal strength, connectivity icons, etc. reside. In most apps I’ve used developers tend to do one of two things there:

  • leave it
  • hide it

An example here is Microsoft’s Facebook app (yes, even the first party apps do this), take a look

This is a pretty decent looking app (yes it violates a bunch of “Modern UI” guidelines but it does look decent). However, the black system tray at the top of the screen breaks the experience. It feels like the app lies on top of the homescreen, while this is actually true it’s a better user experience to suck the user completely into the application.

Another option for the Facebook app would be to hide the system tray, this won’t break the experience for the user on the visual side.

But this solution has another downside, the Facebook app needs an active internet connection to work, suppose the app throws an error saying that your internet connection is down, what’s your first reaction? You check the signal strength and / or wifi connectivity icon, and where do those live? In the system tray that is hidden now, so the user needs to exit the app to check the system tray (same goes for checking the time).

Only hide the system tray when your app absolutely requires it, like a game that needs all the screen estate it can get.

So let’s try a third solution, something a lot of Windows Phone developers tend to forget or don’t know is possible, we can style the system tray. This is what the Facebook app could look like

By simply giving the system tray the same color as the header bar of the app we’ve give the app a little extra while still having a visible system tray.

I used this approach in my Traffic Chat app

Same story in this app, it looks much more like a part of the OS instead of “just an app”.

Let’s do it!

It’s actually very easy to get this done.

In your Windows Phone application, navigate to the App.xaml page. In that page there should be an Application.Resources tag. As you might (should) know, we can define application wide styles here, if we don’t provide a key to a style it applies to all controls of the specified type throughout the app. Sounds easy enough, let’s do it.

Code Snippet
  1. <Style TargetType="phone:PhoneApplicationPage">
  2.     <Setter Property="shell:SystemTray.BackgroundColor" Value="Red" />
  3.     <Setter Property="shell:SystemTray.ForegroundColor" Value="Green" />
  4. </Style>

The style has a target type of PhoneApplicationPage, the class that is used by all pages in a Windows Phone app. We set the backgroundcolor to Red and the Foregroundcolor to Green, this will look very pretty right? Glimlach

If we run the app now you’ll see that nothing has changed. A downside of this is that not providing a key doesn’t work for the PhoneApplicationPage, so we’ll need to name the style and apply it to every page in the application.

Change the above code to this (add a key, name it whatever you want)

Code Snippet
  1. <Style x:Key="DefaultPageStyle" TargetType="phone:PhoneApplicationPage">
  2.     <Setter Property="shell:SystemTray.BackgroundColor" Value="Red" />
  3.     <Setter Property="shell:SystemTray.ForegroundColor" Value="Green" />
  4. </Style>

And on every page that you want to style the systemtray, apply the style (line 15 in this code block).

Code Snippet
  1. <phone:PhoneApplicationPage
  2.     x:Class="PhoneApp1.MainPage"
  3.     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4.     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5.     xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
  6.     xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
  7.     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  8.     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  9.     mc:Ignorable="d"
  10.     FontFamily="{StaticResource PhoneFontFamilyNormal}"
  11.     FontSize="{StaticResource PhoneFontSizeNormal}"
  12.     Foreground="{StaticResource PhoneForegroundBrush}"
  13.     SupportedOrientations="Portrait" Orientation="Portrait"
  14.     shell:SystemTray.IsVisible="True"
  15.     Style="{StaticResource DefaultPageStyle}">

If we run the app now we’ll get a “beautiful” styled system tray.

 

Conclusion

Styling the system tray is something that is often overlooked. Spend some time on this, it’ll make your app look even better without annoying your users with a hidden system tray. It’s easy to do and doesn’t take a lot of time.

Download the Green/Red system tray app from my SkyDrive


Tags:

.Net | Devices | WP7 | WP8 | XAML

Navigating pages in WP8 like in Win8

by Nico

Currently, there are quite some inconsistencies between the Windows Phone SDK and the Windows 8 SDK. One of the very first that you’ll run into when developing for both platforms is the navigation api. The navigation api is used for navigating between different pages inside your app. It contains a method to navigate to a certain page, a method to navigate back one page, a few properties and so on. The thing that you’ll probably use most is the Navigate method and here’s quite a big difference between both platforms. For example, this is how you navigate to a page in Windows Phone

Code Snippet
  1. NavigationService.Navigate(new Uri("/SecondPage.xaml", UriKind.Relative));

And this is the same but in Windows 8

Code Snippet
  1. NavigationService.Navigate(typeof (SecondPage));

The Windows 8 way of navigating has one big advantage, intellisense. By navigating to a type instead of a Uri we eliminate the chance for typos or that we keep forgetting the first “/” in the Uri, or forgetting to mark it as Relative. All things I believe we’ve run into at least once before.

The service

Let’s build our own NavigationService for Windows Phone that supports navigating to a type, just like in Windows 8.

One important thing to remember when using this class is that the namespace of the page you want to navigate to has to be the same as the folder structure where your page lives in. For example, if you have a SecondPage.xaml that sits in a Views folder then the namespace should be MyApp.Views and the complete class name is MyApps.Views.SecondPage

First some properties

Code Snippet
  1. private PhoneApplicationFrame _rootFrame;
  2.  
  3. public bool CanGoBack { get { return _rootFrame.CanGoBack; } }
  4. public bool CanGoForward { get { return _rootFrame.CanGoForward; } }
  5.  
  6. public object RootFrame
  7. {
  8.     get { return _rootFrame; }
  9.     set
  10.     {
  11.         _rootFrame = (PhoneApplicationFrame)value;
  12.     }
  13. }

Our NavigationService needs a reference to the application’s RootFrame, the NavigationService in my case implements an interface that lives in a PCL. That PCL has no idea what PhoneApplicationFrame is so I made the property an object, the reason for the interface is that I might want to build this exact same service for other platforms.

CanGoBack and CanGoForward are read-only properties that just pass the values from the rootframe properties.

Next we’ll have a look at the most important function, navigating to another page.

Code Snippet
  1. public bool Navigate(Type destination)
  2. {
  3.     try
  4.     {
  5.         string fqname = destination.FullName;
  6.         var path = Regex.Split(fqname, @"\.");
  7.  
  8.         string destinationUri = string.Empty;
  9.  
  10.         for (int i = 1; i < path.Length; i++)
  11.         {
  12.             destinationUri = destinationUri + "/" + path[i];
  13.         }
  14.  
  15.         _rootFrame.Navigate(new Uri(destinationUri + ".xaml", UriKind.Relative));
  16.  
  17.         return true;
  18.     }
  19.     catch (Exception)
  20.     {
  21.         return false;
  22.     }
  23. }

The method takes in a Type, that type will be the page we want to reach. First thing we do is getting the full name of the type (namespace + class name), once we have that we can split the full name at each dot using a very simple Regular Expression. The first part of the namespace will be the app name, that’s something we don’t need so the for loop starts at the second item (index 1). The for loop will start building a string, the result will be something like “/Views/SecondPage.xaml”. Once we have that string we can navigate as usual by calling the Navigate function on the rootframe and passing in the Uri. Quite simple, and very effective. Other things I did was mapping some functions of the rootframe into my service like GoForward, GoBack, RemoveBackEntry and ResetBackStack. I’ve also created some overloads so that the service can still navigate the good old way by passing in either a string or a Uri.

Using the service

Using the service is pretty straightforward. You’ll need an instance of it in your app, one that’s available throughout the entire app. So either use an IOC or create a static property in your App.xaml.cs, in this example we’ll go with the App.xaml.cs way, just to keep it short.

In App.xaml.cs add this

Code Snippet
  1. public static NavigationService NavigationService { get; set; }

Then look for the InitializePhoneApplication method in App.xaml.cs (the one that says “Don’t add any additional code to this method”) and add some code to it Glimlach (lines 18 & 19)

Code Snippet
  1. // Do not add any additional code to this method
  2. private void InitializePhoneApplication()
  3. {
  4.     if (phoneApplicationInitialized)
  5.         return;
  6.  
  7.     // Create the frame but don't set it as RootVisual yet; this allows the splash
  8.     // screen to remain active until the application is ready to render.
  9.     RootFrame = new PhoneApplicationFrame();
  10.     RootFrame.Navigated += CompleteInitializePhoneApplication;
  11.  
  12.     // Handle navigation failures
  13.     RootFrame.NavigationFailed += RootFrame_NavigationFailed;
  14.  
  15.     // Handle reset requests for clearing the backstack
  16.     RootFrame.Navigated += CheckForResetNavigation;
  17.  
  18.     NavigationService = new NavigationService();
  19.     NavigationService.RootFrame = RootFrame;
  20.  
  21.     // Ensure we don't initialize again
  22.     phoneApplicationInitialized = true;
  23. }

Line 18 instantiates the service and line 19 sets the rootframe property, these two lines of code are the most important ones in the app.

Add some page to the app, make sure that the namespace is correct, add a button on the first page and set this as code for the button.

Code Snippet
  1. private void Button_Click(object sender, RoutedEventArgs e)
  2. {
  3.     App.NavigationService.Navigate(typeof (SecondPage));
  4. }

This will call the Navigate function on the static property in App.xaml.cs, pass in the type of the page and our NavigationService will do the rest.

Conclusion

In this post I’ve shown you a way to mimic the Windows 8 way of navigating between pages. Using this can make it easier to share code between platforms.

There are only two differences between this method and the native Windows 8 implementation.

  • We need to do some plumbing in App.xaml.cs to make the service work
  • We can’t pass parameters into the navigation, but 1) that  should be doable and 2) you shouldn’t do that. Use some messaging mechanism to send data between views / viewmodels

To end this, here’s the complete class and interface that I use regularly in my projects

Interface (lives in a PCL project)

Code Snippet
  1. /// <summary>
  2. /// Allows page navigation in the app, RootFrame needs to be set in App.xaml
  3. /// </summary>
  4. public interface INavigationService
  5. {
  6.     /// <summary>
  7.     /// The rootframe for the app, this will take care of all the navigation
  8.     /// </summary>
  9.     object RootFrame { get; set; }
  10.  
  11.     /// <summary>
  12.     /// true when there's a page on the backstack
  13.     /// </summary>
  14.     bool CanGoBack { get; }
  15.  
  16.     /// <summary>
  17.     /// true when there's a page on the forwardstack
  18.     /// </summary>
  19.     bool CanGoForward { get; }
  20.  
  21.     /// <summary>
  22.     /// go one step back on the backstack
  23.     /// </summary>
  24.     void GoBack();
  25.  
  26.     /// <summary>
  27.     /// go one step forward on the stack
  28.     /// </summary>
  29.     void GoForward();
  30.  
  31.     /// <summary>
  32.     /// resets the entire backstack
  33.     /// </summary>
  34.     void ResetBackstack();
  35.  
  36.     /// <summary>
  37.     /// remove the last entry from the backstack
  38.     /// </summary>
  39.     void RemoveBackEntry();
  40.  
  41.     /// <summary>
  42.     /// navigate to a page using the type of the page
  43.     /// </summary>
  44.     /// <param name="destination">the type of the page we want to navigate to</param>
  45.     /// <param name="parameter">an optional parameter</param>
  46.     /// <returns>true/false</returns>
  47.     bool Navigate(Type destination);
  48.  
  49.     /// <summary>
  50.     /// navigate to a page using a uri string, paramers are passed using querystring
  51.     /// </summary>
  52.     /// <param name="uri">string pointing to the page we want to navigate too</param>
  53.     /// <returns></returns>
  54.     bool Navigate(string uri);
  55.  
  56.     /// <summary>
  57.     /// navigate to a page using a uri, paramers are passed using querystring
  58.     /// </summary>
  59.     /// <param name="uri">uri we want to navigate too</param>
  60.     /// <returns></returns>
  61.     bool Navigate(Uri uri);
  62. }

Implementation in a Windows Phone project

Code Snippet
  1. public class NavigationService : INavigationService
  2. {
  3.     private PhoneApplicationFrame _rootFrame;
  4.  
  5.     public bool CanGoBack { get { return _rootFrame.CanGoBack; } }
  6.     public bool CanGoForward { get { return _rootFrame.CanGoForward; } }
  7.  
  8.     public object RootFrame
  9.     {
  10.         get { return _rootFrame; }
  11.         set
  12.         {
  13.             _rootFrame = (PhoneApplicationFrame)value;
  14.         }
  15.     }
  16.  
  17.     public void GoBack()
  18.     {
  19.         if (!_rootFrame.CanGoBack) return;
  20.  
  21.         _rootFrame.GoBack();
  22.     }
  23.  
  24.     public void ResetBackstack()
  25.     {
  26.         _rootFrame.BackStack.GetEnumerator().Reset();
  27.     }
  28.  
  29.     public void RemoveBackEntry()
  30.     {
  31.         _rootFrame.RemoveBackEntry();            
  32.     }
  33.  
  34.     public void GoForward()
  35.     {
  36.         if (!_rootFrame.CanGoForward) return;
  37.  
  38.         _rootFrame.GoForward();
  39.     }
  40.  
  41.     public bool Navigate(Type destination)
  42.     {
  43.         try
  44.         {
  45.             string fqname = destination.FullName;
  46.             var path = Regex.Split(fqname, @"\.");
  47.  
  48.             string destinationUri = string.Empty;
  49.  
  50.             for (int i = 1; i < path.Length; i++)
  51.             {
  52.                 destinationUri = destinationUri + "/" + path[i];
  53.             }
  54.  
  55.             _rootFrame.Navigate(new Uri(destinationUri + ".xaml", UriKind.Relative));
  56.  
  57.             return true;
  58.         }
  59.         catch (Exception)
  60.         {
  61.             return false;
  62.         }
  63.     }
  64.  
  65.     public bool Navigate(string uri)
  66.     {
  67.         try
  68.         {
  69.             _rootFrame.Navigate(new Uri(uri, UriKind.Relative));
  70.  
  71.             return true;
  72.         }
  73.         catch (Exception)
  74.         {
  75.             return false;
  76.         }
  77.     }
  78.  
  79.     public bool Navigate(Uri uri)
  80.     {
  81.         try
  82.         {
  83.             _rootFrame.Navigate(uri);
  84.  
  85.             return true;
  86.         }
  87.         catch (Exception)
  88.         {
  89.             return false;
  90.         }
  91.     }
  92. }

Enjoy!


Tags:

.Net | WP8 | PCL | XAML

Traffic Chat: My new Windows Phone 8 app

by Nico

I launched a new Windows Phone 8 app last week called Traffic Chat. A friend of mine came up what the idea of having a chat with other drivers that are stuck in the same traffic jam as you are, perfect idea for a smartphone app.

The way the app works is actually fairly easy, the app detects the street that you’re on, takes your license plate (the plate is saved into the Isolated Storage Settings so it only needs to be entered on first start). The apps sends that data to the server (powered by SignalR and running on Azure Websites), the server checks if a chatroom with the name of the street already exists, if it doesn’t it creates it first, and then enters you as a user, with your license plate as username, into the chatroom.

The great thing about the app is that it hardly requires any user interaction to get started. Since you’re still behind the weel of a car this was very important to me, safety first. Once the app launches it starts detecting immediately with a big pulsating icon to show that it’s still working, if something goes wrong the icon turns red and a big retry button appears.

Even the chatting can be done hands free through speech-to-text.

And as usual, once the app was released I noticed a small mistake on my part, once you’re chatting there’s a button to let your social networks know that you’re using the app but the link that should point to the app actually points to MSDN, oops. An update for this is submitted and should be live this week.

So, try out the app whenever you’re stuck in traffic, but do be careful. Any features missing? Or have some cool idea? Get in touch and I’ll see what I can do, props will be given where needed of course Glimlach

Download the app


Tags:

Making Resharper and MVVM Light’s ViewModelBase play nice

by Nico

ReSharper and MVVM Light are probably my two most used pieces of software. I can’t live without Resharper’s refactoring skills and doing any kind of XAML development without using MVVM Light is just crazy (my opinion of course Glimlach).

One of the more annoying things in XAML based software is the need to write full properties that call the PropertyChanged event in the setter. If your project is data intensive you’ll probably need a lot of those properties, luckily Resharper can help us there.

The Resharper solution

When you make your class implement INotifyPropertyChanged it requires you to implement its members, Resharper comes with a built-in implementation, just press alt-enter and behold.

After inserting the code Resharper asks if you want to include some annotations in your project, and these annotations make some magic happen, so I would strongly advice to add them.

Once you click Yes you’ll notice that a new class is added to your project under the Properties folder. The INotifyPropertyChanged implementation looks like this

Code Snippet
  1. public class MyBase : INotifyPropertyChanged
  2. {
  3.     public event PropertyChangedEventHandler PropertyChanged;
  4.  
  5.     [NotifyPropertyChangedInvocator]
  6.     protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
  7.     {
  8.         PropertyChangedEventHandler handler = PropertyChanged;
  9.         if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
  10.     }
  11. }

As you can see Resharpes uses the CallerMemberName attribute new in .net 4.5, this way we won’t have to specify the property’s name anymore when we call OnPropertyChanged. Line 5 is what will make the next piece of Resharper magic happen.

Now we want to add some properties to the class and make them call OnPropertyChanged in the setter. I start of with an autoproperty

Code Snippet
  1. public string Name { get; set; }

Next I alt-enter the property. Resharper now checks the class and its baseclasses if available, if one of those has the NotifyPropertyChangedInvocator attribute it will show an extra option in the menu.

Selecting that option will turn the autoproperty into

Code Snippet
  1. private string _name;
  2. public string Name
  3. {
  4.     get { return _name; }
  5.     set
  6.     {
  7.         if (value == _name) return;
  8.         _name = value;
  9.         OnPropertyChanged();
  10.     }
  11. }

Mission accomplished, we create a bunch of autoproperties, alt-enter them and save a lot of time.

The MVVM Light problem

The MVVM Light viewmodels all inherit from ViewModelBase, ViewModelBase inherits from ObservableObject and ObservableObject implements INotifyPropertyChanged

Code Snippet
  1. public abstract class ViewModelBase : ObservableObject, ICleanup

 

Code Snippet
  1. public class ObservableObject : INotifyPropertyChanged

And here’s the MVVM Light implementation of INotifyPropertyChanged

Code Snippet
  1. public event PropertyChangedEventHandler PropertyChanged;
  2.  
  3. protected virtual void RaisePropertyChanged(string propertyName)
  4. {
  5.     VerifyPropertyName(propertyName);
  6.  
  7.     var handler = PropertyChanged;
  8.     if (handler != null)
  9.     {
  10.         handler(this, new PropertyChangedEventArgs(propertyName));
  11.     }
  12. }
  13.  
  14. public void VerifyPropertyName(string propertyName)
  15. {
  16.     var myType = GetType();
  17.  
  18.     if (!string.IsNullOrEmpty(propertyName)
  19.         && myType.GetProperty(propertyName) == null)
  20.     {
  21.         throw new ArgumentException("Property not found", propertyName);
  22.     }
  23. }

A nice implementation but it lacks the attributes required for Resharper to implement a backing field with change notification. Meaning that we still have to write the implementation ourselves or we need to build our own ViewModelBase and implement INotifyPropertyChanged our self, which is a bit of a shame since this nice implementation already exists.

A solution

The solution I came up with does require us to build a viewmodelbase, but to be honest I tend to do that in almost every project, for example for an IsDataLoading bindable property, that’s useful in every page. The ViewModel base class that we’ll build inherits from ViewModelBase and overrides the RaisePropertyChanged. Do make sure that the annotations.cs class from Resharper is present in your project.

Code Snippet
  1. public class MyBase : ViewModelBase
  2. {
  3.      /// <summary>
  4.     /// This gives us the ReSharper option to transform an autoproperty into a property with change notification
  5.     /// Also leverages .net 4.5 callermembername attribute
  6.     /// </summary>
  7.     /// <param name="property">name of the property</param>
  8.     [NotifyPropertyChangedInvocator]
  9.  
  10.     protected override void RaisePropertyChanged([CallerMemberName]string property = "")
  11.     {
  12.         base.RaisePropertyChanged(property);
  13.     }
  14. }

The overriden method just calls its base method and passes in the parameter. But thanks to .net 4.5 and the attribute we can now use the CallerMemberName attribute and Resharper’s alt-enter magic in MVVM Light while still having the ViewModelBase.

And the result of that action is like you would suspect

Code Snippet
  1. private string _name;
  2. public string Name
  3. {
  4.     get { return _name; }
  5.     set
  6.     {
  7.         if (value == _name) return;
  8.         _name = value;
  9.         RaisePropertyChanged();
  10.     }
  11. }

Conclusion

In this post I’ve shown a quick fix I use to make two of my favorite bits play together nicely without changing any of the native implementations, I still use the ViewModelBase way of notifying when a property changed and I can make use of Resharper to quickly write those properties.


Tags:

Community day 2013

by Nico

Yesterday was the day for Community day 2013, already the seventh edition. A bunch of user groups working together to create a great agenda of presentations by community, for community.

This seventh edition was in my opinion the best one so far, the quality of the talks I followed was incredible and I’ve learned quite a lot.

I also did my own talk on SignalR and Windows Phone 8. Here you can find my slidedeck.

 

And my demos can be found here (this includes the chat demo, the leap motion demo and the Photobeamer clone.

As mentioned during my talk, the photobeamer clone is something I did a blogpost on a while back, for those interested the post can be found here

I had a blast at Community day 2013 and I’m already looking forward to the next edition!


Tags:

.Net | Community | LeapMotion | WP8 | Talk | signalr | XAML

Run your WP8 app on two emulators simultaneously

by Nico

I’m currently working on a Windows Phone 8 project that requires two devices. Those devices talk to each other through a SignalR service. Thanks to Hyper-V I’m able to test/debug this project on two instances of the Windows Phone 8 emulator (I usually pick the WVGA and WVGA 512MB versions). What I used to do is deploy the XAP to one emulator and debug it on the second. I need to do this every time I change the app, I got bored of doing this manually so it was about time to get this automated.

Since Visual Studio 2012 builds the app everytime its codebase changes I can use the post-build script to do this, after all the app should only install itself on both emulators when it’s changed (I did spent time looking for a solution to let the script run every time I hit the debug button but it looks like there’s no way to do this in VS2012).

The point of the post-build script is to fire up the emulator when needed, deploy the app and run it. Visual Studio 2012 debug will fire up the second emulator, deploy the app there and launch it with debug, meaning that only one emulator will have a debugger attached.

Choosing the emulator for the script

Microsoft has provided a command line tool for deploying xap files, both onto a device and onto the emulators. Before we can start using it we’ll need to know the correct index of the emulator that we want the script to use. Copy-paste this script into a textfile and save as a .bat file, double click it and you should see a list of all available emulators on your machine (provided that you have the Windows Phone 8 SDK installed of course).

Code Snippet
  1. cd "%ProgramFiles(x86)%\Microsoft SDKs\Windows Phone\v8.0\Tools\XAP Deployment"
  2. XapDeployCmd.exe /EnumerateDevices
  3. pause

XapDeployCmd.exe is the commandline tool for everything related to XAP deployments. More information on the tool can be found on MSDN

Choose the emulator of your choose from the list and remember its index.

Building the script

Time to start building the script. In your Windows Phone 8 project, go to the project properties to the Build Events tab. In the Post-build event command line box enter this script.

Code Snippet
  1. cd %ProgramFiles(x86)%\Microsoft SDKs\Windows Phone\v8.0\Tools\XAP Deployment
  2. XapDeployCmd.exe /installlaunch $(TargetDir)$(ProjectName)_$(ConfigurationName)_$(PlatformName).xap /targetdevice:1

The first line of the script navigates the command line to the folder where the XapDeployCmd lives (this is the default install path, the tool comes with the WP8 SDK). The second line launches the tool and passes the necessary parameters. the installaunch parameter states that the app should install (or update) the app and launch it when finished. After the installaunch parameter we need to state the path to the xap file, by default (when using the debug configuration in VS2012) it’s in the bin/debug folder and is called something like MyWPApp_debug_anycpu.xap. To make the script easy to transfer over I’ve used variables instead of hardcoding the path and the xap name. Here’s a quick rundown.

Variable Meaning
$(TargetDir) the full path to the outputdirectory (for example: c:\users\nico\documents\Projects\MyWPApp\bin\debug\)

Keep in mind that the last “\” is always included when using this variable
$(ProjectName) The name of the project (didn’t see that one coming, did you? Glimlach) (for example: MyWPApp)
$(ConfigurationName) The used configuration, for example ”release” or “debug”
$(PlatformName) The selected CPU architecture, for example “AllCpu”, “ARM”, “x86”

With these powers variables combined we get the full path to the xap file. The last parameter specifies the to use emulator by passing in the index that we determined at the beginning of this post.

And that’s it. Rebuild your solution and watch the emulator start app, deploy and launch your app. Now every time that you change the code of the app and hit the debug button it will build and deploy to both emulators. One of the emulators should have those debug numbers on the side, making it easy to recognize which one has the debugger attached.

Conclusion

Using a very simple post-build script and the in the WP8 included XapDeployCmd tool it’s very easy to deploy an application to two devices simultaneously. This isn’t needed very often but when building something that connects users to each other (like a chat application or a multiplayer game) it can save you quite some hassle. Just make sure that your script uses another emulator version than Visual Studio 2012.

 


Tags:

.Net | Devices | WP7 | WP8 | msbuild

Error tracking with RayGun and free t-shirts!

by Nico

I received a mail from Mindscape stating that their product called Raygun was coming along nicely and if I was interested in trying it out and blogging my finding. I would receive a bunch of t-shirts to hand out during user group events. So here’s me, writing my findings of RayGun (which is actually a cool product) and hoping to receive free t-shirts, the things I do for community Glimlach

RayGun

So what is RayGun? RayGun plugs into your apps and sends errors to the server. You as the developer receive an email stating that a new error has been found.

What’s great here is that you can resolve the error here with one click, the second link will open the error details on the site and immediately change its status to Resolved.

If you view the error you get all the information that you expect from a service like Raygun. Information about the device that the error occurred on, the used resolution (always 800x480 for Windows Phone as that is the base resolution, all apps are upscaled from there but it still reports as 800x480) and of course the complete stacktrace.

You can even view RAW data in JSON format.

Code Snippet
  1. { "MachineName": "RM-821_eu_belgium_464", "Error": { "Data": [], "ClassName": "System.Exception", "Message": "Exception: raygun test", "StackTrace": [ { "LineNumber": 0, "ClassName": " at RayGunDemo.MainPage.ButtonBase_OnClick(Object sender, RoutedEventArgs e)" }, { "LineNumber": 0, "ClassName": " at System.Windows.Controls.Primitives.ButtonBase.OnClick()" }, { "LineNumber": 0, "ClassName": " at System.Windows.Controls.Button.OnClick()" }, { "LineNumber": 0, "ClassName": " at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)" }, { "LineNumber": 0, "ClassName": " at System.Windows.Controls.Control.OnMouseLeftButtonUp(Control ctrl, EventArgs e)" }, { "LineNumber": 0, "ClassName": " at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName)" } ] }, "Environment": { "ProcessorCount": 0, "OSVersion": "Win32NT 8.0.10211.0", "WindowBoundsWidth": 480, "WindowBoundsHeight": 800, "CurrentOrientation": "PortraitUp", "TotalPhysicalMemory": 0, "AvailablePhysicalMemory": 0, "TotalVirtualMemory": 0, "AvailableVirtualMemory": 0, "DiskSpaceFree": [], "DeviceName": "RM-821_eu_belgium_464", "UtcOffset": 0, "Locale": "Nederlands (België)" }, "Client": { "Name": "Raygun4Net", "Version": "Mindscape.Raygun4Net.WindowsPhone, Version=1.0.5.0, Culture=neutral, PublicKeyToken=null", "ClientUrl": "https://github.com/MindscapeHQ/raygun4net" } }

You can add comments to errors, assign people to them, all in all RayGun feels very complete. The mail arrived immediately after the error was thrown, shows up nicely on the dashboard, both the Windows Phone emulator and my Lumia 920 over 3G reported the error perfectly.

Implementing RayGun

Implementing RayGun in your app is very straigthforward, go to http://www.raygun.io and register for a trial account (pricing can be found here http://raygun.io/pricing). Once your account is registered you arrive at a page that tells you the steps to integrate RayGun with your app.

Nifty feature here is that your api key is integrated in the sample code that they give you, so it’s just copy/paste. It may sound stupid but I really liked that sense of detail.

First thing we need to do is add RayGun through NuGet.

Bit weird here is that a readme file pops open stating that for Windows Phone I need to Reference the "Mindscape.Raygun4Net.WindowsPhone.dll but NuGet is smart enough to reference the correct DLL depending on the platform that you’re developing for.

Second step is adding a property of the RayGunClient to App.xaml.cs and instantiating it with the api key.

Code Snippet
  1. public static RaygunClient RaygunClient { get; set; }
  2.  
  3. /// <summary>
  4. /// Constructor for the Application object.
  5. /// </summary>
  6. public App()
  7. {
  8.     RaygunClient = new RaygunClient("<your key here>");

And for the initial setup there’s one step left. In the Application_UnhandledException method add the actual call to the RayGun servers (line 4).

Code Snippet
  1. // Code to execute on Unhandled Exceptions
  2. private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
  3. {
  4.     RaygunClient.Send(e);
  5.  
  6.     if (Debugger.IsAttached)
  7.     {
  8.         // An unhandled exception has occurred; break into the debugger
  9.         Debugger.Break();
  10.     }
  11. }

And from now on, any unhandled exception is logged in RayGun and you’re notified immediately when they occur. Try it out by adding a button on your mainpage and set this as click event.

Code Snippet
  1. private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
  2. {
  3.     throw new Exception("raygun test");
  4. }

Since the RayGunClient in this example is a static property in App.xaml.cs you can reuse it anywhere in your project. You can even start creating completely custom errorlogs by passing in a RayGunMessage instance in the Send method.

Conclusion

RayGun works as advertised, no problem there at all. The dashboard looks great, is easy to navigate and shows all the necessary information. Crash reports arrive really fast and have nice little details like a one-click link to resolve an error. Small mistake in the readme file that opens when adding the NuGet package can be forgiven (who reads readme files anyway?)

Will it be a great success? I don’t know. There’s quite a lot of competition out there, services that offer the same stuff as Mindscape does with RayGun but often times they are either free or provide a limited free service for hobby developers. Personally, I feel that MindScape should include a free price plan as well, limited in such a way that it’s only suitable for hobby projects of course since everyone needs to make a living. But those hobby developers can create buzz around the product so that professionals will pick up on it as well.

By the way, this post only talks about the Windows Phone part of RayGun but it supports a wide array of platforms like ASP.net, JavaScript, PHP, Ruby on rails, Java and ColdFusion.

So all in all, great product, works as advertised! If you want a t-shirt come to the next MADN user group event after the summer break and hopefully we’ll have some to hand out!


Tags:

.Net | Community | XAML

IIS Express and the Windows Phone 8 emulator

by Nico

As an app developer you’re bound to run into a situation where you’re building both an app and a mobile website or REST based service. That means that you’re testing the ASP.net project in IIS Express while using the Windows Phone 8 emulator, since the emulator behaves like a separate device on the network you can’t use localhost to contact your IIS Express server.

There are a few ways to tackle this problem, you can finish the web project first and deploy it to a webserver. If your WP8 emulator is configured correctly it should have internet access and will be able to connect to your server just fine. A second option is to install an IIS server in your network and deploy to there from Visual Studio. But the most easy option would be to use the IIS Express server that comes with Visual Studio. That’s certainly an option but requires some (small) configuration tweaks.

First things first

We’ll need a webproject of course to test this. I’ll create a very very basic ASP.net WebAPI project and a very basic Windows Phone 8 app that will run in the emulator. I could have made my point with a simple hello world website and the mobile browser but that’s just boring.

Visual Studio 2012 ships with ASP.net MVC WebAPI, think REST services made ridiculously easy, to start a project select the MVC4 web template in Visual Studio 2012 and give it a name.

 

Once you click OK a second dialog will show up and that one holds the option to start a WebAPI project.

What this gives you is an MVC project with an API controller. This behaves much like the normal controller that you’re used to from MVC but instead of returning a view it returns data in a JSON format (serializing happens with JSON.net by the way, not with the .net serializer). I’m not going to dive very deep in WebAPI, there are a lot of bloggers out there that know way more about this stuff than I do. We’ll be using the default GET method from the ValuesController.

Code Snippet
  1. // GET api/values
  2. publicIEnumerable<string> Get()
  3. {
  4.     returnnewstring[] { "value1", "value2" };
  5. }

This just returns a collection of two strings.

Next step is adding a Windows Phone 8 project to the solution (a simple basic project started from the normal template). Now we have two projects in one solution that both need to start up. We could launch the api without debugging and launch the WP8 app in debug mode or we can set them both to launch at debug by selecting multiple startup projects in the solution properties.

You can easily see that the settings have applied successfully if no project in the solution is bold anymore.

Okay, time to hook them up. We’ll need two things, the IP address of the pc running IIS Express and the port that the ASP.net project will use. Getting the IP address should be easy, just enter ipconfig in a command prompt. To find out the port, navigate to the properties of the ASP.net project.

In the Web tab of the properties you can see the project url for the website, that url contains the port that will be used.

Time for some coding, in the Windows Phone app, add a constant that holds the url to the website.

Code Snippet
  1. privateconststring Url = "http://192.168.0.116:7145/";

And the code to fetch the REST data

Code Snippet
  1. privatevoid FetchData()
  2. {
  3.     WebClient client = newWebClient();
  4.  
  5.     client.DownloadStringCompleted += ClientOnDownloadStringCompleted;
  6.  
  7.     client.DownloadStringAsync(newUri(Url + "api/values"));
  8. }

The callback will use Json.net (added through NuGet) to deserialize the values into a List<string> that is then set as the ItemsSource of a LongListSelector.

Code Snippet
  1. privatevoid ClientOnDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs downloadStringCompletedEventArgs)
  2. {
  3.     if (downloadStringCompletedEventArgs.Error == null)
  4.     {
  5.         var values = JsonConvert.DeserializeObject<List<string>>(downloadStringCompletedEventArgs.Result);
  6.  
  7.         ValueList.ItemsSource = values;
  8.     }
  9. }

All in all pretty easy but this won’t work because IIS Express is bound to localhost only by default, we’ll need to change the config to allow external connections.

The configuration of IIS Express can be found in the applicationhost.config xml file found in %userprofile%\documents\IISExpress\config (just copy-paste this path into the Windows 8 start screen and press enter)

Open the XML file and search for the name of your ASP.net project. It should look something like this

Code Snippet
  1. <site name="IisExpressDemo" id="13">
  2.     <application path="/" applicationPool="Clr4IntegratedAppPool">
  3.         <virtualDirectory path="/" physicalPath="c:\users\nico\documents\visual studio 2012\Projects\IisExpressDemo\IisExpressDemo" />
  4.     </application>
  5.     <bindings>
  6.         <binding protocol="http" bindingInformation="*:7145:localhost" />
  7.     </bindings>
  8. </site>

Line 6 contains the binding, copy this line and paste it underneath, change localhost with the IP address of your pc, like this

Code Snippet
  1. <site name="IisExpressDemo" id="13">
  2.     <application path="/" applicationPool="Clr4IntegratedAppPool">
  3.         <virtualDirectory path="/" physicalPath="c:\users\nico\documents\visual studio 2012\Projects\IisExpressDemo\IisExpressDemo" />
  4.     </application>
  5.     <bindings>
  6.         <binding protocol="http" bindingInformation="*:7145:localhost" />
  7.         <binding protocol="http" bindingInformation="*:7145:192.168.0.116" />
  8.     </bindings>
  9. </site>

Close the IIS Express server if it’s still running and run the project.

Now there’s a pretty big chance that you’ll see this.

Visual Studio 2012 needs to be started as administrator to allow IIS Express to create bindings for external connections, so if you get this error, close and restart Visual Studio 2012 as an administrator.

Run the project again and the Windows Phone application should be able to fetch the data from the API.

 

Conclusion

In this post I’ve talked about opening up your IIS Express development server to allow external connections. This is needed to allow the Windows Phone 8 emulator to connect to websites or APIs hosted locally. It’s basically two steps

  • Add the IP address of your pc to the IIS config
  • Launch Visual Studio as administrator to be able to set the binding

 


Tags:

.Net | Devices | IIS | Metro | Web development | WP8

  Log in

About the author

Hi,

My name is Nico, I’m an MVP Windows Platform Development living in Belgium.
I’m currently employed as a .NET consultant at RealDolmen, one of Belgium’s leading IT single source providers.

I'm also founding member and board member of the Belgian Metro App Developer Network, a user group focussed on Windows 8 and Windows Phone development. If you're in Belgium feel free to drop by if we're doing an event. http://www.madn.be

Since June 2012 I'm a proud member of Microsoft's Extended Experts Team Belgium. And in February 2013 I became a member of DZone's Most Valuable Bloggers family.

In 2013 I became a book author and wrote "Windows 8 app projects, XAML & C# edition".

In 2014 I received the MVP award for the very first time.

I hope to get feedback from my readers either through comments, mail (nico_vermeir@hotmail.com), twitter, facebook, …

 

mvp

 

mvp

 

 

MeetLogo

 

MVBLogo

mybook

 

Month List