0 Comments

RESTXamarintTitleLogo

Lets have a look at how we can consume a REST based web service in a Xamarin.Forms application. In this blog post we will look at how an ASP.Net WebAPI service that is hosted on Azure and how it can be consumed in the Portable Class Library (PCL) of your Xamarin.Forms application and write a small UI to interact with the REST service. Please note that I used Visual Studio 2013 while creating the example for this project.

 

Creating the backend

An ASP.Net WebAPI can be considered as a headless website, so many of the concepts of ASP.Net MVC apply but we will not be writing any HTML, JavaScript and CSS code for displaying the data as it will simply provide the data through the controller. Per default the controller can return the data serialized to JSON or XML. For this example I have created two controllers, one will just simply return a string and return it as the content of the HTTP package:

public class BasicController : ApiController
{
// GET: api/Basic/5
public string Get(int id)
{
return string.Format("You entered: {0}", id);
}
}

The second one will return a serialized object to the caller. The default settings will request the data to be serialized with JSON but we will come to that later on. The second controller looks as follows:

public class ObjectController : ApiController
{
// GET: api/Object/5
public NumberWrapper Get(int id)
{
return new NumberWrapper{WrappedNumber = string.Format("You entered: {0}", id)};
}
}

And the Plain Old CLR Object (POCO) which is used you can see here:

public class NumberWrapper
{
public string WrappedNumber { get; set; }
}

So all pretty straight forward, now lets look at how we can consume the service once it is running.

Note: You can publish this webservice on Azure which makes it really easy to access it from phones and other Virtual Machines (VMs) as you will not be hassled with firewall settings and therefore can focus at the task at hand.

 

Consuming a REST service in the PCL

For consuming the REST service we will need to install the WebHttpClient NuGet package from Microsoft. So lets open up the package manager by right-clicking on the solution and then searching for WebHttpClient, add the NuGet package to the PCL, Android, iOS and Windows Phone Project. For deserializing the JSON we will use the JSON.Net library from James Newton-King, so search once more for JSON.Net and install it again for all the client projects.

The communication with the backend is created in HttpWrapper.cs, the BasicController simply the Content of the result is read and passed back:

public async Task<string> GetBasicDataAsync(int i)
{
var uri = string.Format("https://xamarinwebapiservice.azurewebsites.net/api/basic/{0}", i);

var result = await _httpClient.GetAsync(uri);

return await result.Content.ReadAsStringAsync();
}

When we call the ObjectController we receive the JSON in the Content of the result and have to deserialize it first:

public async Task<NumberWrapper> GetNumberWrapperDataAsync(int i)
{
var uri = string.Format("{0}object/{1}", BaseUrl, i);

var result = await _httpClient.GetAsync(uri);

var jsonNumberWRapper = await result.Content.ReadAsStringAsync();

return JsonConvert.DeserializeObject<NumberWrapper>(jsonNumberWRapper);
}

So far so good now lets create a small UI to Consume the service and its controllers.

 

The client UI

I’ll be using MVVM Light in the UI for the data binding, on a former post you can find an introduction on how to get started with MVVM Light. The UI lets you pick a number and you can choose the call by selecting the according button:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WebApiXamarinForms.View.MainPage">
<StackLayout>
<Picker SelectedIndex="{Binding SelectedNumberIndex}" HorizontalOptions="CenterAndExpand" Title="Numbers">
<Picker.Items>
<x:String>1</x:String>
<x:String>2</x:String>
<x:String>3</x:String>
<x:String>4</x:String>
<x:String>5</x:String>
<x:String>6</x:String>
<x:String>7</x:String>
<x:String>8</x:String>
<x:String>9</x:String>
<x:String>10</x:String>
</Picker.Items>
</Picker>
<Button Text="Basic Submit" Command="{Binding BasicSubmitCommand}" HorizontalOptions="CenterAndExpand"></Button>
<Button Text="Object Submit" Command="{Binding ObjectSubmitCommand}" HorizontalOptions="CenterAndExpand"></Button>
<ActivityIndicator IsRunning="{Binding CallingService}"></ActivityIndicator>
<Label Text="{Binding Response}" VerticalOptions="Center" HorizontalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage>

Note that the Picker control does not yet support data binding so this is currently the only way how you can set the values.

In the MainViewModel.cs the calls to the service are made during the command invokes and the result is written accordingly to the UI. Here the BasicSubmitCommand:

private async void GetBasicResponseAsync()
{
CanGetBasicResponse = false;
CallingService = true;

Response = await _webService.GetBasicDataAsync(_numbers[SelectedNumberIndex]);

CallingService = false;
CanGetBasicResponse = true;
}

And the ObjectSubmitCommand:

private async void GetObjectResponseAsync()
{
CanGetBasicResponse = false;
CallingService = true;

var numberWrapper = await _webService.GetNumberWrapperDataAsync(_numbers[SelectedNumberIndex]);
Response = numberWrapper.WrappedNumber;

CallingService = false;
CanGetBasicResponse = true;
}

Conclusion

In this blog post we took a quick look at how a WebAPI controller is setup. Further we looked at how HTTP calls are created on the Xamarin.Forms client and how responses can be parsed and used within a program. We also saw how we can consume objects that are received as JSON strings from a web service.

You can find the entire source code on GitHub.

0 Comments

ApplePushOverview

Lets have a look on how we can enable a Xamarin.iOS i.e. Xamarin.Forms app to receive push notifications. I’m using the Azure Notification Hub on the backend which simplifies the integration of the push services on the backend.

Requirements

To implement push notifications on iOS you will need to have:

  1. An apple developer account
  2. An iOS device
  3. An Apple computer you can access
  4. A valid Azure Account

You will need an iOS Device as push notifications can not be tested in the simulator.

Further this blog post will assume that you are using Visual Studio as a development environment.

Setting up the backend

On the backend we will have to do the following steps:

  1. Generate a certificate
  2. Registering your app for push notifications
  3. Configuring the notification portal on Azure

Generating the certificate

For sending push notifications with an apple device we will need to have a Push certificate. The certificate is generated with the Keychain Access tool.

On OSX you can search all the programs by using the finder which you can find at the top right and has the symbol of a magnifying glass.

GenerateCertificate

Select Keychain Access, Certificate Assistantand then Request a Certificate From a Certificate Authority

CertificateDetails

Enter your user Email and common name. And ensure you select save to disk. After selecting continue make give your cert a good name and save it to the desktop.

Registering your app for push notifications

Login to the Apple developer portal, go to the App IDs, select your app and click onto Edit.Create certificate

Select Create Certificate… (for now lets choose the Development SSL Certificate,click onto Continue and under Choose File… select and upload the previously generated certificate.

ConfigurePushNotificaiton

Final step download the generate certificate and double click to import it to your keychain. For Azure we will need to export the cert into a p12 file. So open up Keychain Access. Under Keychainsselect login, then under Category select Keys, now find the Pushcertifiacte (expand it and export the private key) right-click, click Export,choose a good name, select .p12 format and finally click Save.

Make sure that the iOS device you want to use for testing the push notification is added to the app.

Configuring the notification portal on Azure

Now lets first setup the backend so we can send the push notification messages, which will require a valid Azure Account. Log on to Azure and perform the following steps:

  1. Click +NEW
  2. Click APP SERVICES, then SERVICE BUS and then select NOTIFICATION HUB
  3. Enter name, select the region and if you haven't done so already enter your namespace (this option does not appear if you already have created a namespace).

azuremessagehub

After the notification hub is created we will have to configure it for use with Windows Phone Silverlight. Select your notification hub (namespace), which you will find under the SERVICE BUS tab and then select the notification hub you just created.

Under apple notification settings select upload. Upload the p12 file and the password according to what you entered when it was exported. Under Mode select Sandbox for a development certificate or Production for a production certificate. This will depend upon the certificate you upload for the usage.

Setup the client

After setting up the backend we now can connect our app to the push service, as we will be using Azure for the push service we will need to add the Azure Messaging component which you can download by right-clicking on your iOS project then select Get More Components, search for Azure Messaging and add the component to the project.

Registering for notificaitons

Now let’s start wiring up our app to the push service, this is all done in AppDelegate.cs.

First update the FinishedLaunching() method as follows:

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
Forms.Init();

//Register for remote notifications iOS 8 and higher
if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
{
var settings = UIUserNotificationSettings.GetSettingsForTypes(UIUserNotificationType.Sound |
UIUserNotificationType.Alert | UIUserNotificationType.Badge, null);

UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
UIApplication.SharedApplication.RegisterForRemoteNotifications();
}

//Register for remote notifications iOS 7 and bellow
else
{
const UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert
| UIRemoteNotificationType.Badge
| UIRemoteNotificationType.Sound;

UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
}

LoadApplication(new App());
return base.FinishedLaunching(app, options);
}

Please note that the registering has changed starting of iOS 8, depending on which version of iOS you are planning on targeting you might only need one of registrations above. If you aren’t using a Xamarin.Forms app it should look as follows:

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
//Register for remote notifications iOS 8 and higher

if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
{
var settings = UIUserNotificationSettings.GetSettingsForTypes(UIUserNotificationType.Sound |
UIUserNotificationType.Alert | UIUserNotificationType.Badge, null);

UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
UIApplication.SharedApplication.RegisterForRemoteNotifications();
}

//Register for remote notifications iOS 7 and lower
else
{
const UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert
| UIRemoteNotificationType.Badge
| UIRemoteNotificationType.Sound;

UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
}

return true;
}

To finish of the Registration we add the following member variable within AppDelegate.cs 

private SBNotificationHub Hub { get; set; }

and override the RegisteredForRemoteNotifications() method as follows:

 

public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
const string notificationHubConnectionString = "Endpoint=sb://mallibone.servicebus.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;[email protected]";
const string notificationHubName = "mallibone";

Hub = new SBNotificationHub(notificationHubConnectionString, notificationHubName);

Hub.UnregisterAllAsync(deviceToken, (error) =>
{
if (error != null)
{
Console.WriteLine("Error calling Unregister: {0}", error.ToString());
return;
}

var deviceId = Convert.ToBase64String(deviceToken.ToArray());
var tag = Guid.NewGuid().ToString();
var tags = new List<string> { tag };

Hub.RegisterNativeAsync(deviceToken, new NSSet(tags.ToArray()), (errorCallback) =>
{
if (errorCallback != null)
{
Console.WriteLine("RegisterNativeAsync error: " + errorCallback.ToString());
return;
}
});
});
}

Receiving push notifications

Now lets make our device vibrate the first time a message is received. Therefore we override the ReceivedRemoteNotification in (as you might have already guessed) AppDelegate.cs:

 

public override void ReceivedRemoteNotification(UIApplication application, NSDictionary notificationData)
{
SystemSound.Vibrate.PlaySystemSound();
}

Sending the message

In the server explorer double click on your notification hub which will open a window that allows you to send push notifications and check on your device registrations (all within VS :)). Now under type select Apple (APNS)and then Default. For now we do not have to alter the message so if your app successfully started and is humming beside you just click on Send.

Receiving notifications in the background

In many apps you want to handle waking from a push notification differently then when a notification arrives while the user is using the app e.g. when waking from a push notification we want to navigate directly to where the action originated from, when the app is running we might simply want to notify the user that something happened by vibrating the device.

For handling waking up from a push notification we have to add the RecievedRemoteNotification method as follows:

public override void ReceivedRemoteNotification(UIApplication application, NSDictionary notificationData)
{
if (application.ApplicationState == UIApplicationState.Inactive
|| application.ApplicationState == UIApplicationState.Background)
{
// Handle notification on wake
return;
}

SystemSound.Vibrate.PlaySystemSound();
}

 

Starting the app on a notification

To make thing interesting wake and startup have to handled differently on iOS so to ensure a consistent behaviour between wake and startup we will have to modify the FinishedLaunching method as follows:

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();

if (options != null && options.ContainsKey(UIApplication.LaunchOptionsRemoteNotificationKey))
{
var notificationData = options[UIApplication.LaunchOptionsRemoteNotificationKey] as NSDictionary;
// process notification data
}

LoadApplication(new App());
return base.FinishedLaunching(app, options);
}

If you are using Xamarin Forms be sure that you call LoadApplication after handling the notification.

Adding parameters to the notification

Adding parameters is a great way to pass application specific information to the app that is not intended for the user. Adding parameters to the message can be done easily be extending the message as shown in this sample:

{"aps":{"alert":"Notification Hub test notification"},"parameterOne":"SomeIdentifier","parameterTwo":"1234"}

The parameters parsed in ReceivedRemoteNotification:

public override void ReceivedRemoteNotification(UIApplication application, NSDictionary notificationData)
{
if (application.ApplicationState == UIApplicationState.Inactive
|| application.ApplicationState == UIApplicationState.Background)
{
// Handle notification on wake
return;
}


var parameeterOne = notificationData["parameterOne"].ToString();
var parameterTwo = Convert.ToInt32(notificationData["parameterOne"].ToString());

// Send message i.e. process push notification


SystemSound.Vibrate.PlaySystemSound();
}

And in FinishedLaunching method:

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();

if (options != null && options.ContainsKey(UIApplication.LaunchOptionsRemoteNotificationKey))
{
var notificationData = options[UIApplication.LaunchOptionsRemoteNotificationKey] as NSDictionary;
var parameeterOne = notificationData["parameterOne"].ToString();
var parameterTwo = Convert.ToInt32(notificationData["parameterOne"].ToString());

// Send message i.e. process push notification
// process notification data
}

LoadApplication(new App());
return base.FinishedLaunching(app, options);
}

 

Conclusion

Adding push notifications for a Xamarin.iOS or Xamarin.Forms app is possible and with Azure as the backend will allow you to streamline the integration for other platforms such as Windows Phone or Android.

0 Comments
PushNotification

Push notifications are a great way to inform users about an update. This might be a chat message, breaking news or simply put alert your users that something of interest has occurred and is probably worth her while to check it out. Now when we look at push notifications there is obviously the receiver which resembles the Phone. On the sending part you will find some backend service e.g. a web server that initiates the push notification. I'll be using a Xamarin.Forms application for this demo, but all these steps apply without any difference for a standard Windows Phone Silverlight application.

NotificationHubBigPicture

Setting up the backend

Now lets first setup the backend so we can send the push notification messages, which will require a valid Azure Account. Log on to Azure and perform the following steps:

  1. Click +NEW
  2. Click APP SERVICES, then SERVICE BUS and then select NOTIFICATION HUB
  3. Enter name, select the region and if you haven't done so already enter your namespace (this option does not appear if you already have created a namespace).
CreateNotificationHub

After the notification hub is created we will have to configure it for use with Windows Phone Silverlight. Select your notification hub (namespace), which you will find under the SERVICE BUS tab and then select the notification hub you just created.

Note you may have multiple notification hubs under the same namespace, this can be really handy once your app is in the field and you are developing on the next version you can separate the Dev and Production notification hubs very easy this way.

NHMPNSSetupNow for development the easiest way is to simply Enable unauthenticated push notifications. and save the changes. which will not require registering the app at this point. If you already have done so you can also upload the certificate you can download from the Windows Developer Portal.

Enabling your App to receive push notifications

Creating a Xamarin.Forms project is done really easily. We will now perform the following steps:

  1. Permissions for Remote Notifications
  2. Install the Azure Messaging NuGet Package
  3. Register your app on startup
  4. Sending the first message

Permissions for Remote Notifications

Open the WMAppManifest.xml file which is located under the Properties of the Windows Phone Project. Under Capabilities ensure that ID_CAP_PUSH_NOTIFICATION is enabled.

mobile-app-enable-push-wp8

Install the Azure Messaging NuGet Package

Open the NuGet Package Manager by right clicking on the Windows Phone project and select Manage NuGet Packages.... In the Online tab search for the package WindowsAzure.Messaging.Managed and install it in your Windows Phone project.

Register your app on startup

Now lets wire the backend service together with our mobile app. This is done in the App.xaml.cs file which is located in the root of your Windows Phone Project. Within the Application_Launching method add the following code:

var channel = HttpNotificationChannel.Find("ChannelName");
if (channel == null)
{
channel = new HttpNotificationChannel("ChannelName");
channel.Open();
channel.BindToShellToast();
}

channel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(async (o, args) =>
{
var hub = new NotificationHub("<hub name>", "<connection string>");
await hub.RegisterNativeAsync(args.ChannelUri.ToString());
});

Which will require the following usings:

using Microsoft.Phone.Notification;
using Microsoft.WindowsAzure.Messaging;

Note that the Channel name is individual to your application and is used to check if your app has already registered for a push notification. We are currently only binding to the ShellToast notification type. Now lets enter the hub name and connection string for your messaging hub. Due to the superb integration of azure within Visual Studio open the Server Explorer (if not already present on the left side you can find it under the VIEW menu), open the Azure dropdown, then the Notification Hubs and select the notification hub you created before in my example it's named mallibone which resembles the hub name. In your properties sub-view you will see the connection strings. You will have to open the view by clicking on the three points to get the full connection string, for the client we will only need the listening connection string as we do not intend to write push notifications from the mobile client in this app.

Copy the connection string and insert it in the notification hub creation within the Application_Launching method.

private void Application_Launching(object sender, LaunchingEventArgs e)
{
var channel = HttpNotificationChannel.Find("MalliboneHelloWorldChannel");
if (channel == null)
{
channel = new HttpNotificationChannel("MalliboneHelloWorldChannel");
channel.Open();
channel.BindToShellToast();
}

channel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(async (o, args) =>
{
var hub = new NotificationHub("mallibone", "Endpoint=sb://mallibone.servicebus.windows.net/;SharedAccessKeyName=DefaultListenSharedAccessSignature;SharedAccessKey=SOME_MUMBOJUMBO_AKA_THE_KEY
await hub.RegisterNativeAsync(args.ChannelUri.ToString());
});
}

Sending the first message

You could now send a notification and would receive toast notification if your app is not open. And by tapping on the toast notification your app would open. But for our first message lets have the app running and have the app vibrate when a message comes in.

Handling push notifications when the app is running

Within App.xaml.cs add the following line to the Application_Launching method:

channel.ShellToastNotificationReceived += (o, args) => VibrationDevice.GetDefault().Vibrate(TimeSpan.FromMilliseconds(300));

Which will require the using:

using Windows.Phone.Devices.Notification;

Ensure you can launch your application before proceeding.

Sending the message

In the server explorer double click on your notification hub which will open a window that allows you to send push notifications and check on your device registrations (all within VS :)). Now under type select Windows Phone MPNS and then Toast. For now we do not have to alter the message so if your app successfully started and is humming beside you just click on Send.

Adding parameters to the notification

Sending notifications is a great way to inform your users but often you do not only want a fancy Toast tile and then just start your app to the root page but rather give the user the content he just selected by tapping on the toast notification. So lets extend the message by adding a parameter to the toast message:

<?xml version="1.0" encoding="utf-8"?>
<wp:Notification xmlns:wp="WPNotification">
<wp:Toast>
<wp:Text1>NotificationHub</wp:Text1>
<wp:Text2>Test message</wp:Text2>
<wp:Param>/MainPage.xaml?helloParameter=1234&amp;secondParameter=SomeKey</wp:Param>
</wp:Toast>
</wp:Notification>

Parsing parameters on the client

Now when we start the app from the background i.e. by clicking on the toast notification, we will be starting the app with and can parse for the parameters in the MainPage.xaml.cs in the OnNavigetTo method:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);

const string helloParameter = "helloParemeter";
const string secondParameter = "secondParameter";

if (NavigationContext.QueryString.ContainsKey(helloParameter) && NavigationContext.QueryString.ContainsKey(secondParameter))
{
var message = string.Format("Received toast with HelloParameter {0} and SecondParemter {1}",
NavigationContext.QueryString[helloParameter], NavigationContext.QueryString[secondParameter]);
MessageBox.Show(message);

}
}

Parsing the parameters when the app is running is done, as you might have already guessed in the App.xaml.cs class by extending the event handler.

Conclusion

Adding push notifications can be a rich addition to your application as it allows you to interact with your user and give him news within seconds after something has happened. By using Azure you can really streamline the integration of push services across multiple platforms as I will show you in future posts.

References

http://azure.microsoft.com/en-us/documentation/articles/notification-hubs-windows-phone-get-started/

0 Comments

Push-Notifications

With iOS 8+ the way you register for push notifications has changed a bit. So if you want your app to continue receiving push notifications on iOS 8 and above you will need to adjust your registration to this:

var settings = UIUserNotificationSettings.GetSettingsForTypes(UIUserNotificationType.Sound
| UIUserNotificationType.Alert | UIUserNotificationType.Badge, null);

UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
UIApplication.SharedApplication.RegisterForRemoteNotifications();

To continue supporting iOS7 and bellow you can still register as before or just use the lines bellow:

if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
{
var settings = UIUserNotificationSettings.GetSettingsForTypes(UIUserNotificationType.Sound
| UIUserNotificationType.Alert | UIUserNotificationType.Badge, null);

UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
UIApplication.SharedApplication.RegisterForRemoteNotifications();
}
else
{
const UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert
| UIRemoteNotificationType.Badge
| UIRemoteNotificationType.Sound;

UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
}

Conclusion

I stumbled over this one as I was following along the Azure push notification hub tutorial. Hope it will be of some help to you.