Tutorial: Push notifications to Xamarin.iOS apps using Azure Notification Hubs

Overview

This tutorial shows you how to use Azure Notification Hubs to send push notifications to an iOS application. You create a blank Xamarin.iOS app that receives push notifications by using the Apple Push Notification service (APNs).

When you're finished, you are able to use your notification hub to broadcast push notifications to all the devices running your app. The finished code is available in the NotificationHubs app sample.

In this tutorial, you create/update code to do the following tasks:

  • Generate the certificate signing request file
  • Register your app for push notifications
  • Create a provisioning profile for the app
  • Configure your notification hub for iOS push notifications
  • Send test push notifications

Prerequisites

  • Azure subscription. If you don't have an Azure subscription, create a free Azure account before you begin.

  • Latest version of Xcode

  • An iOS 10 (or later version) compatible device

  • Apple Developer Program membership.

  • Visual Studio for Mac

    Note

    Because of configuration requirements for iOS push notifications, you must deploy and test the sample application on a physical iOS device (iPhone or iPad) instead of in the simulator.

Completing this tutorial is a prerequisite for all other Notification Hubs tutorials for Xamarin.iOS apps.

Generate the certificate-signing request file

The Apple Push Notification Service (APNs) uses certificates to authenticate your push notifications. Follow these instructions to create the necessary push certificate to send and receive notifications. For more information on these concepts, see the official Apple Push Notification Service documentation.

Generate the Certificate Signing Request (CSR) file, which Apple uses to generate a signed push certificate.

  1. On your Mac, run the Keychain Access tool. It can be opened from the Utilities folder or the Other folder on the Launchpad.

  2. Select Keychain Access, expand Certificate Assistant, and then select Request a Certificate from a Certificate Authority.

    Use Keychain Access to request a new certificate

  3. Select your User Email Address, enter your Common Name value, make sure that you specify Saved to disk, and then select Continue. Leave CA Email Address blank as it isn't required.

    Required certificate information

  4. Enter a name for the CSR file in Save As, select the location in Where, and then select Save.

    Choose a file name for the certificate

    This action saves the CSR file in the selected location. The default location is Desktop. Remember the location chosen for the file.

Next, register your app with Apple, enable push notifications, and upload the exported CSR to create a push certificate.

Register your app for push notifications

To push notifications to an iOS app, register your application with Apple and also register for push notifications.

  1. If you haven't already registered your app, browse to the iOS Provisioning Portal at the Apple Developer Center. After that, sign in with your Apple ID, select Identifiers, select App IDs, and finally select + to register a new app.

    iOS Provisioning Portal App IDs page

  2. Update the following three values for your new app, and then select Continue:

    • Name: Type a descriptive name for your app in the Name box in the App ID Description section.

    • Bundle Identifier: In the Explicit App ID section, enter a Bundle Identifier of the form <Organization Identifier>.<Product Name> as mentioned in the App Distribution Guide. The Organization Identifier and Product Name values must match the organization identifier and product name you use when you create your Xcode project. In the following screenshot, the NotificationHubs value is used as an organization identifier and the GetStarted value is used as the product name. Make sure the Bundle Identifier value matches the value in your Xcode project, so that Xcode will use the correct publishing profile.

    • Push Notifications: Check the Push Notifications option in the App Services section.

      Form to register a new App ID

      This action generates your App ID and requests that you confirm the information. Select Register to confirm the new App ID.

      After you select Register, you see the Registration complete screen as shown in the following image. Select Done.

      App ID registration complete showing entitlements

  3. In the Developer Center, under App IDs, locate the app ID that you created and select its row.

    App ID list

    Select the app ID to display the app details, and then select the Edit button at the bottom.

    Edit App ID page

  4. Scroll to the bottom of the screen and select the Create Certificate button under the Development Push SSL Certificate section.

    Create certificate for App ID button

    You now see the Add iOS Certificate assistant.

    Note

    This tutorial uses a development certificate. The same process is used when registering a production certificate. Just make sure that you use the same certificate type when sending notifications.

  5. Select Choose File, browse to the location where you saved the CSR file from the first task, and then select Generate.

    Generated certificate CSR upload page

  6. After the portal creates the certificate, select the Download button and then select Done.

    Generated certificate download page

    The certificate is downloaded and saved to your computer in your Downloads folder.

    Locate certificate file in the Downloads folder

    Note

    By default, the downloaded development certificate is named aps_development.cer.

  7. Select the downloaded push certificate aps_development.cer.

    This action installs the new certificate in the Keychain, as shown in the following image:

    Keychain access certificates list showing new certificate

    Note

    Although the name in your certificate might be different, the name will be prefixed with Apple Development iOS Push Services.

  8. In Keychain Access, right-click the new push certificate that you created in the Certificates category. Select Export, name the file, select the .p12 format, and then select Save.

    Export certificate as p12 format

    Make a note of the file name and location of the exported .p12 certificate. They are used to enable authentication with APNs.

    Note

    This tutorial creates a file named QuickStart.p12. Your file name and location might be different.

Create a provisioning profile for the app

  1. In the iOS Provisioning Portal, select Provisioning Profiles, select All, and then select + to create a new profile. You see the Add iOS Provisioning Profile wizard.

    Provisioning profile list

  2. Select iOS App Development under Development as the provisioning profile type, and select Continue.

  3. Next, select the app ID you created from the App ID drop-down list, and select Continue.

    Select the App ID

  4. In the Select certificates window, select your usual development certificate that you used for code signing, and select Continue. This certificate isn't the push certificate you created.

    Select the certificate

  5. Next, select the devices to use for testing, and select Continue.

    Select the devices

  6. Finally, pick a name for the profile in Profile Name, and select Generate.

    Choose a provisioning profile name

  7. When the new provisioning profile is created, choose to download and install it on your Xcode development machine. Then select Done.

    Download the provisioning profile

Create a notification hub

In this section, you create a notification hub and configure authentication with APNs by using the .p12 push certificate that you previously created. If you want to use a notification hub that you've already created, you can skip to step 5.

  1. Sign in to the Azure portal.

  2. Select All services on the left menu, and then select Notification Hubs in the Mobile section. Select the star icon next to the service name to add the service to the FAVORITES section on the left menu. After you add Notification Hubs to FAVORITES, select it on the left menu.

    Azure portal - select Notification Hubs

  3. On the Notification Hubs page, select Add on the toolbar.

    Notification Hubs - Add toolbar button

  4. On the Notification Hub page, do the following steps:

    1. Enter a name in Notification Hub.

    2. Enter a name in Create a new namespace. A namespace contains one or more hubs.

    3. Select a value from the Location drop-down list box. This value specifies the location in which you want to create the hub.

    4. Select an existing resource group in Resource Group, or create a name for a new resource group.

    5. Select Create.

      Azure portal - set notification hub properties

  5. Select Notifications (the bell icon), and then select Go to resource. You can also refresh the list on the Notification Hubs page and select your hub.

    Azure portal - notifications -> Go to resource

  6. Select Access Policies from the list. Note that the two connection strings are available to you. You'll need them later to handle push notifications.

    Important

    Do not use the DefaultFullSharedAccessSignature policy in your application. This is meant to be used in your back end only.

    Azure portal - notification hub connection strings

Configure your notification hub with APNs information

  1. Under Notification Services, select Apple (APNS).

  2. Select Certificate.

  3. Select the file icon.

  4. Select the .p12 file that you exported earlier.

  5. Specify the correct password.

  6. Select Sandbox mode. Use the Production mode only if you want to send push notifications to users who purchased your app from the store.

    Configure APNs certification in Azure portal

You've now configured your notification hub with APNs. You also have the connection strings to register your app and send push notifications.

Configure your notification hub for iOS push notifications

This section walks you through the steps to create a new notification hub and configure authentication with APNs using the .p12 push certificate that you previously created. If you want to use a notification hub that you have already created, you can skip to step 5.

  1. Sign in to the Azure portal.

  2. Select All services on the left menu, and then select Notification Hubs in the Mobile section. Select the star icon next to the service name to add the service to the FAVORITES section on the left menu. After you add Notification Hubs to FAVORITES, select it on the left menu.

    Azure portal - select Notification Hubs

  3. On the Notification Hubs page, select Add on the toolbar.

    Notification Hubs - Add toolbar button

  4. On the Notification Hub page, do the following steps:

    1. Enter a name in Notification Hub.

    2. Enter a name in Create a new namespace. A namespace contains one or more hubs.

    3. Select a value from the Location drop-down list box. This value specifies the location in which you want to create the hub.

    4. Select an existing resource group in Resource Group, or create a name for a new resource group.

    5. Select Create.

      Azure portal - set notification hub properties

  5. Select Notifications (the bell icon), and then select Go to resource. You can also refresh the list on the Notification Hubs page and select your hub.

    Azure portal - notifications -> Go to resource

  6. Select Access Policies from the list. Note that the two connection strings are available to you. You'll need them later to handle push notifications.

    Important

    Do not use the DefaultFullSharedAccessSignature policy in your application. This is meant to be used in your back end only.

    Azure portal - notification hub connection strings

Configure iOS settings for the notification hub

  1. Select Apple (APNS) in the NOTIFICATION SETTINGS group.

  2. Select Certificate, click the file icon, and select the .p12 file that you exported earlier.

  3. Specify the password for the certificate.

  4. Select Sandbox mode. Use the Production mode only if you want to send push notifications to users who purchased your app from the store.

    Configure APNs in Azure portal

    Configure APNs certification in Azure portal

Your notification hub is now configured to work with APNs, and you have the connection strings to register your app and send push notifications.

Connect your app to the notification hub

Create a new project

  1. In Visual Studio, create a new iOS project and select the Single View App template, and click Next

    Visual Studio - Select Application Type

  2. Enter your App Name and Organization identifier, then click Next, then Create

  3. From the Solution view, double-click Info.plist and under Identity make sure your Bundle Identifier matches the one used when creating your provisioning profile. Under Signing ensure that your Developer account is selected under Team, "Automatically manage signing" is selected and your Signing Certificate and Provisioning Profile are automatically selected.

    Visual Studio- iOS App Config

  4. From the Solution view, double-click the Entitlements.plist and ensure that Enable Push Notifications is checked.

    Visual Studio- iOS Entitlements Config

  5. Add the Azure Messaging package. In the Solution view, right-click the project and select Add > Add NuGet Packages. Search for Xamarin.Azure.NotificationHubs.iOS and add the package to your project.

  6. Add a new file to your class, name it Constants.cs and add the following variables and replace the string literal placeholders with the hubname and the DefaultListenSharedAccessSignature noted earlier.

    // Azure app-specific connection string and hub path
    public const string ListenConnectionString = "<Azure DefaultListenSharedAccess Connection String>";
    public const string NotificationHubName = "<Azure Notification Hub Name>";
    
  7. In AppDelegate.cs, add the following using statement:

    using WindowsAzure.Messaging;
    using UserNotifications
    
  8. Declare an instance of SBNotificationHub:

    private SBNotificationHub Hub { get; set; }
    
  9. In AppDelegate.cs, update FinishedLaunching() to match the following code:

    public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
    {
        if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
        {
            UNUserNotificationCenter.Current.RequestAuthorization(UNAuthorizationOptions.Alert | UNAuthorizationOptions.Sound | UNAuthorizationOptions.Sound,
                                                                    (granted, error) =>
            {
                if (granted)
                    InvokeOnMainThread(UIApplication.SharedApplication.RegisterForRemoteNotifications);
            });
        } else if (UIDevice.CurrentDevice.CheckSystemVersion (8, 0)) {
            var pushSettings = UIUserNotificationSettings.GetSettingsForTypes (
                    UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound,
                    new NSSet ());
    
            UIApplication.SharedApplication.RegisterUserNotificationSettings (pushSettings);
            UIApplication.SharedApplication.RegisterForRemoteNotifications ();
        } else {
            UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
            UIApplication.SharedApplication.RegisterForRemoteNotificationTypes (notificationTypes);
        }
    
        return true;
    }
    
  10. In AppDelegate.cs, override the RegisteredForRemoteNotifications() method:

    public override void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
    {
        Hub = new SBNotificationHub(Constants.ListenConnectionString, Constants.NotificationHubName);
    
        Hub.UnregisterAllAsync (deviceToken, (error) => {
            if (error != null)
            {
                System.Diagnostics.Debug.WriteLine("Error calling Unregister: {0}", error.ToString());
                return;
            }
    
            NSSet tags = null; // create tags if you want
            Hub.RegisterNativeAsync(deviceToken, tags, (errorCallback) => {
                if (errorCallback != null)
                    System.Diagnostics.Debug.WriteLine("RegisterNativeAsync error: " + errorCallback.ToString());
            });
        });
    }
    
  11. In AppDelegate.cs, override the ReceivedRemoteNotification() method:

    public override void ReceivedRemoteNotification(UIApplication application, NSDictionary userInfo)
    {
        ProcessNotification(userInfo, false);
    }
    
  12. In AppDelegate.cs, create the ProcessNotification() method:

    void ProcessNotification(NSDictionary options, bool fromFinishedLaunching)
    {
        // Check to see if the dictionary has the aps key.  This is the notification payload you would have sent
        if (null != options && options.ContainsKey(new NSString("aps")))
        {
            //Get the aps dictionary
            NSDictionary aps = options.ObjectForKey(new NSString("aps")) as NSDictionary;
    
            string alert = string.Empty;
    
            //Extract the alert text
            // NOTE: If you're using the simple alert by just specifying
            // "  aps:{alert:"alert msg here"}  ", this will work fine.
            // But if you're using a complex alert with Localization keys, etc.,
            // your "alert" object from the aps dictionary will be another NSDictionary.
            // Basically the JSON gets dumped right into a NSDictionary,
            // so keep that in mind.
            if (aps.ContainsKey(new NSString("alert")))
                alert = (aps [new NSString("alert")] as NSString).ToString();
    
            //If this came from the ReceivedRemoteNotification while the app was running,
            // we of course need to manually process things like the sound, badge, and alert.
            if (!fromFinishedLaunching)
            {
                //Manually show an alert
                if (!string.IsNullOrEmpty(alert))
                {
                    UIAlertView avAlert = new UIAlertView("Notification", alert, null, "OK", null);
                    avAlert.Show();
                }
            }
        }
    }
    

    Note

    You can choose to override FailedToRegisterForRemoteNotifications() to handle situations such as no network connection. This is especially important where the user might start your application in offline mode (for example, Airplane) and you want to handle push messaging scenarios specific to your app.

  13. Run the app on your device.

Send test push notifications

You can test receiving notifications in your app with the Test Send option in the Azure portal. It sends a test push notification to your device.

Azure portal - Test Send

Push notifications are normally sent in a back-end service like Mobile Apps or ASP.NET using a compatible library. If a library is not available for your back-end, you can also use the REST API directly to send notification messages.

Next steps

In this tutorial, you sent broadcast notifications to all your iOS devices registered with the backend. To learn how to push notifications to specific iOS devices, advance to the following tutorial: