Add push notifications to your Xamarin.iOS App

Overview

In this tutorial, you add push notifications to the Xamarin.iOS quick start project so that a push notification is sent to the device every time a record is inserted.

If you do not use the downloaded quick start server project, you will need the push notification extension package. See Work with the .NET backend server SDK for Azure Mobile Apps for more information.

Prerequisites

  • Complete the Xamarin.iOS quickstart tutorial.
  • A physical iOS device. Push notifications are not supported by the iOS simulator.

Register the app for push notifications on Apple's developer portal

Configure your Mobile App to send push notifications

  1. On your Mac, launch Keychain Access. On the left navigation bar, under Category, open My Certificates. Find the SSL certificate that you downloaded in the previous section, and then disclose its contents. Select only the certificate (do not select the private key). Then export it.
  2. In the Azure portal, select Browse All > App Services. Then select your Mobile Apps back end.
  3. Under Settings, select App Service Push. Then select your notification hub name.
  4. Go to Apple Push Notification Services > Upload Certificate. Upload the .p12 file, selecting the correct Mode (depending on whether your client SSL certificate from earlier is production or sandbox). Save any changes.

Your service is now configured to work with push notifications on iOS.

Update the server project to send push notifications

In this section, you update code in your existing Mobile Apps back-end project to send a push notification every time a new item is added. This process is powered by the template feature of Azure Notification Hubs, which enables cross-platform pushes. The various clients are registered for push notifications using templates, and a single universal push can get to all client platforms.

Choose one of the following procedures that matches your back-end project type—either .NET back end or Node.js back end.

.NET back-end project

  1. In Visual Studio, right-click the server project. Then select Manage NuGet Packages. Search for Microsoft.Azure.NotificationHubs, and then select Install. This process installs the Notification Hubs library for sending notifications from the back end.
  2. In the server project, open Controllers > TodoItemController.cs. Then add the following using statements:

    using System.Collections.Generic;
    using Microsoft.Azure.NotificationHubs;
    using Microsoft.Azure.Mobile.Server.Config;
    
  3. In the PostTodoItem method, add the following code after the call to InsertAsync:

    // Get the settings for the server project.
    HttpConfiguration config = this.Configuration;
    MobileAppSettingsDictionary settings =
        this.Configuration.GetMobileAppSettingsProvider().GetMobileAppSettings();
    
    // Get the Notification Hubs credentials for the mobile app.
    string notificationHubName = settings.NotificationHubName;
    string notificationHubConnection = settings
        .Connections[MobileAppSettingsKeys.NotificationHubConnectionString].ConnectionString;
    
    // Create a new Notification Hub client.
    NotificationHubClient hub = NotificationHubClient
    .CreateClientFromConnectionString(notificationHubConnection, notificationHubName);
    
    // Send the message so that all template registrations that contain "messageParam"
    // receive the notifications. This includes APNS, GCM, WNS, and MPNS template registrations.
    Dictionary<string,string> templateParams = new Dictionary<string,string>();
    templateParams["messageParam"] = item.Text + " was added to the list.";
    
    try
    {
        // Send the push notification and log the results.
        var result = await hub.SendTemplateNotificationAsync(templateParams);
    
        // Write the success result to the logs.
        config.Services.GetTraceWriter().Info(result.State.ToString());
    }
    catch (System.Exception ex)
    {
        // Write the failure result to the logs.
        config.Services.GetTraceWriter()
            .Error(ex.Message, null, "Push.SendAsync Error");
    }
    

    This process sends a template notification that contains the item.Text when a new item is inserted.

  4. Republish the server project.

Node.js back-end project

  1. If you haven't already done so, download the quickstart back-end project, or else use the online editor in the Azure portal.
  2. Replace the existing code in todoitem.js with the following code:

    var azureMobileApps = require('azure-mobile-apps'),
    promises = require('azure-mobile-apps/src/utilities/promises'),
    logger = require('azure-mobile-apps/src/logger');
    
    var table = azureMobileApps.table();
    
    table.insert(function (context) {
    // For more information about the Notification Hubs JavaScript SDK,
    // see http://aka.ms/nodejshubs.
    logger.info('Running TodoItem.insert');
    
    // Define the template payload.
    var payload = '{"messageParam": "' + context.item.text + '" }';  
    
    // Execute the insert. The insert returns the results as a promise.
    // Do the push as a post-execute action within the promise flow.
    return context.execute()
        .then(function (results) {
            // Only do the push if configured.
            if (context.push) {
                // Send a template notification.
                context.push.send(null, payload, function (error) {
                    if (error) {
                        logger.error('Error while sending push notification: ', error);
                    } else {
                        logger.info('Push notification sent successfully!');
                    }
                });
            }
            // Don't forget to return the results from the context.execute().
            return results;
        })
        .catch(function (error) {
            logger.error('Error while running context.execute: ', error);
        });
    });
    
    module.exports = table;  
    

    This process sends a template notification that contains the item.text when a new item is inserted.

  3. When you edit the file on your local computer, republish the server project.

Configure your Xamarin.iOS project

Configure the iOS project in Xamarin Studio

  1. In Xamarin.Studio, open Info.plist, and update the Bundle Identifier with the bundle ID that you created earlier with your new app ID.

  2. Scroll down to Background Modes. Select the Enable Background Modes box and the Remote notifications box.

  3. Double-click your project in the Solution Panel to open Project Options.
  4. Under Build, choose iOS Bundle Signing, and select the corresponding identity and provisioning profile you just set up for this project.

    This ensures that the project uses the new profile for code signing. For the official Xamarin device provisioning documentation, see Xamarin Device Provisioning.

Configure the iOS project in Visual Studio

  1. In Visual Studio, right-click the project, and then click Properties.
  2. In the properties pages, click the iOS Application tab, and update the Identifier with the ID that you created earlier.

  3. In the iOS Bundle Signing tab, select the corresponding identity and provisioning profile you just set up for this project.

    This ensures that the project uses the new profile for code signing. For the official Xamarin device provisioning documentation, see Xamarin Device Provisioning.

  4. Double-click Info.plist to open it, and then enable RemoteNotifications under Background Modes.

Add push notifications to your app

  1. In QSTodoService, add the following property so that AppDelegate can acquire the mobile client:

    public MobileServiceClient GetClient {
        get
        {
            return client;
        }
        private set
        {
            client = value;
        }
    }
    
  2. Add the following using statement to the top of the AppDelegate.cs file.

    using Microsoft.WindowsAzure.MobileServices;
    using Newtonsoft.Json.Linq;
    
  3. In AppDelegate, override the FinishedLaunching event:

     public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
     {
         // registers for push for iOS8
         var settings = UIUserNotificationSettings.GetSettingsForTypes(
             UIUserNotificationType.Alert
             | UIUserNotificationType.Badge
             | UIUserNotificationType.Sound,
             new NSSet());
    
         UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
         UIApplication.SharedApplication.RegisterForRemoteNotifications();
    
         return true;
     }
    
  4. In the same file, override the RegisteredForRemoteNotifications event. In this code you are registering for a simple template notification that will be sent across all supported platforms by the server.

    For more information on templates with Notification Hubs, see Templates.

    public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
    {
        MobileServiceClient client = QSTodoService.DefaultService.GetClient;
    
        const string templateBodyAPNS = "{\"aps\":{\"alert\":\"$(messageParam)\"}}";
    
        JObject templates = new JObject();
        templates["genericMessage"] = new JObject
        {
            {"body", templateBodyAPNS}
        };
    
        // Register for push with your mobile app
        var push = client.GetPush();
        push.RegisterAsync(deviceToken, templates);
    }
    
  5. Then, override the DidReceivedRemoteNotification event:

     public override void DidReceiveRemoteNotification (UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
     {
         NSDictionary aps = userInfo.ObjectForKey(new NSString("aps")) as NSDictionary;
    
         string alert = string.Empty;
         if (aps.ContainsKey(new NSString("alert")))
             alert = (aps [new NSString("alert")] as NSString).ToString();
    
         //show alert
         if (!string.IsNullOrEmpty(alert))
         {
             UIAlertView avAlert = new UIAlertView("Notification", alert, null, "OK", null);
             avAlert.Show();
         }
     }
    

Your app is now updated to support push notifications.

Test push notifications in your app

  1. Press the Run button to build the project and start the app in an iOS capable device, then click OK to accept push notifications.

    Note

    You must explicitly accept push notifications from your app. This request only occurs the first time that the app runs.

  2. In the app, type a task, and then click the plus (+) icon.

  3. Verify that a notification is received, then click OK to dismiss the notification.
  4. Repeat step 2 and immediately close the app, then verify that a notification is shown.

You have successfully completed this tutorial.