iOS アプリへのプッシュ通知の追加

概要

このチュートリアルでは、iOS クイックスタート プロジェクトにプッシュ通知を追加して、レコードが挿入されるたびにプッシュ通知が送信されるようにします。

ダウンロードしたクイックスタートのサーバー プロジェクトを使用しない場合は、プッシュ通知拡張機能パッケージを追加する必要があります。 詳細については、「Azure Mobile Apps 用 .NET バックエンド サーバー SDK の操作」を参照してください。

iOS シミュレーターでは、プッシュ通知はサポートされていません。 物理 iOS デバイスと Apple Developer Program メンバーシップが必要です。

通知ハブを構成する

Azure App Service の Mobile Apps 機能は Azure Notification Hubs を使用してプッシュを送信するため、ここではモバイル アプリの通知ハブを構成します。

  1. Azure Portal で、 [App Services] に移動し、アプリ バックエンドを選択します。 [設定][プッシュ] を選択します。

  2. 通知ハブ リソースをアプリに追加するには、 [接続] を選択します。 ハブを作成することも、既存のハブに接続することもできます。

    ハブの構成

これで、通知ハブが Mobile Apps のバックエンド プロジェクトに接続されました。 後でこの通知ハブを構成して、デバイスにプッシュ通知を送信するプラットフォーム通知システム (PNS) に接続します。

アプリをプッシュ通知用に登録する

  • アプリのアプリ ID を登録します。 ワイルドカード アプリ ID ではなく明確なアプリ ID を作成し、 [Bundle ID (バンドル ID)] には、Xcode クイックスタート プロジェクト内に含まれるバンドル ID を使用します。 [Push Notifications (プッシュ通知)] チェック ボックスをオンにすることも重要です。
  • 次に、プッシュ通知を構成するための準備として、"開発" または "配布" SSL 証明書を作成します。

プッシュ通知を送信するように Azure を構成する

  1. お使いの Mac で、 Keychain Accessを起動します。 左側のナビゲーション バーで、 [分類][自分の証明書] を開きます。 前のセクションでダウンロードした SSL 証明書を見つけ、その内容を開示します。 (秘密キーを選択せずに) 証明書のみを選択します。 次に、それをエクスポートします。
  2. Azure Portal[すべて参照] > [App Services] の順に選択します。 次に、Mobile Apps バックエンドを選択します。
  3. [設定][App Service Push](App Service プッシュ) を選択します。 次に、通知ハブの名前を選択します。
  4. [Apple Push Notification Service] > [証明書のアップロード] の順に選択します。 (前の手順のクライアント SSL 証明書が実稼働環境用かサンドボックス用かに応じて) 適切なモードを選択して、.p12 ファイルをアップロードします。 すべての変更を保存します。

これで、iOS のプッシュ通知と連携するようにサービスが構成されました。

プッシュ通知を送信するようにバックエンドを更新する

.NET バックエンド (C#) :

  1. Visual Studio でサーバー プロジェクトを右クリックし、 [NuGet パッケージの管理] をクリックして Microsoft.Azure.NotificationHubs を見つけ、 [インストール] をクリックします。 これにより、バックエンドから通知を送信するために必要な Notification Hubs ライブラリがインストールされます。

  2. バックエンドの Visual Studio プロジェクトで、 [コントローラー] > [TodoItemController.cs] の順に開きます。 ファイルの先頭に、次の using ステートメントを追加します。

    using Microsoft.Azure.Mobile.Server.Config;
    using Microsoft.Azure.NotificationHubs;
    
  3. PostTodoItem メソッドを次のコードに置き換えます。

    public async Task<IHttpActionResult> PostTodoItem(TodoItem item)
    {
        TodoItem current = await InsertAsync(item);
        // 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);
    
        // iOS payload
        var appleNotificationPayload = "{\"aps\":{\"alert\":\"" + item.Text + "\"}}";
    
        try
        {
            // Send the push notification and log the results.
            var result = await hub.SendAppleNativeNotificationAsync(appleNotificationPayload);
    
            // 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");
        }
        return CreatedAtRoute("Tables", new { id = current.Id }, current);
    }
    
  4. サーバー プロジェクトを発行します。

Node.js バックエンド:

  1. バックエンド プロジェクトを設定します。

  2. todoitem.js テーブル スクリプトを次のコードで置き換えます。

    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();
    
    // When adding record, send a push notification via APNS
    table.insert(function (context) {
        // For details of the Notification Hubs JavaScript SDK, 
        // see https://aka.ms/nodejshubs
        logger.info('Running TodoItem.insert');
    
        // Create a payload that contains the new item Text.
        var payload = "{\"aps\":{\"alert\":\"" + context.item.text + "\"}}";
    
        // Execute the insert; Push as a post-execute action when results are returned as a Promise.
        return context.execute()
            .then(function (results) {
                // Only do the push if configured
                if (context.push) {
                    context.push.apns.send(null, payload, function (error) {
                        if (error) {
                            logger.error('Error while sending push notification: ', error);
                        } else {
                            logger.info('Push notification sent successfully!');
                        }
                    });
                }
                return results;
            })
            .catch(function (error) {
                logger.error('Error while running context.execute: ', error);
            });
    });
    
    module.exports = table;
    
  3. ローカル コンピューターでファイルを編集するときは、サーバー プロジェクトを再発行します。

プッシュ通知をアプリに追加する

Objective-C:

  1. QSAppDelegate.m で、iOS SDK と QSTodoService.hをインポートします。

    #import <MicrosoftAzureMobile/MicrosoftAzureMobile.h>
    #import "QSTodoService.h"
    
  2. didFinishLaunchingWithOptionsQSAppDelegate.m で、return YES; の直前に次の行を挿入します。

    UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
    [[UIApplication sharedApplication] registerForRemoteNotifications];
    
  3. QSAppDelegate.mで、次のハンドラー メソッドを追加します。 これで、アプリケーションがプッシュ通知をサポートするように更新されました。

    // Registration with APNs is successful
    - (void)application:(UIApplication *)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    
        QSTodoService *todoService = [QSTodoService defaultService];
        MSClient *client = todoService.client;
    
        [client.push registerDeviceToken:deviceToken completion:^(NSError *error) {
            if (error != nil) {
                NSLog(@"Error registering for notifications: %@", error);
            }
        }];
    }
    
    // Handle any failure to register
    - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:
    (NSError *)error {
        NSLog(@"Failed to register for remote notifications: %@", error);
    }
    
    // Use userInfo in the payload to display an alert.
    - (void)application:(UIApplication *)application
            didReceiveRemoteNotification:(NSDictionary *)userInfo {
        NSLog(@"%@", userInfo);
    
        NSDictionary *apsPayload = userInfo[@"aps"];
        NSString *alertString = apsPayload[@"alert"];
    
        // Create alert with notification content.
        UIAlertController *alertController = [UIAlertController
                                        alertControllerWithTitle:@"Notification"
                                        message:alertString
                                        preferredStyle:UIAlertControllerStyleAlert];
    
        UIAlertAction *cancelAction = [UIAlertAction
                                        actionWithTitle:NSLocalizedString(@"Cancel", @"Cancel")
                                        style:UIAlertActionStyleCancel
                                        handler:^(UIAlertAction *action)
                                        {
                                            NSLog(@"Cancel");
                                        }];
    
        UIAlertAction *okAction = [UIAlertAction
                                    actionWithTitle:NSLocalizedString(@"OK", @"OK")
                                    style:UIAlertActionStyleDefault
                                    handler:^(UIAlertAction *action)
                                    {
                                        NSLog(@"OK");
                                    }];
    
        [alertController addAction:cancelAction];
        [alertController addAction:okAction];
    
        // Get current view controller.
        UIViewController *currentViewController = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
        while (currentViewController.presentedViewController)
        {
            currentViewController = currentViewController.presentedViewController;
        }
    
        // Display alert.
        [currentViewController presentViewController:alertController animated:YES completion:nil];
    
    }
    

Swift:

  1. 次の内容を含む ClientManager.swift ファイルを追加します。 %AppUrl% を Azure モバイル アプリ バックエンドの URL に置き換えます。

    class ClientManager {
        static let sharedClient = MSClient(applicationURLString: "%AppUrl%")
    }
    
  2. ToDoTableViewController.swift で、let client を初期化する MSClient 行を次の行に置き換えます。

    let client = ClientManager.sharedClient
    
  3. AppDelegate.swift で、func application の本文を次のように置き換えます。

    func application(application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        application.registerUserNotificationSettings(
            UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound],
                categories: nil))
        application.registerForRemoteNotifications()
        return true
    }
    
  4. AppDelegate.swiftで、次のハンドラー メソッドを追加します。 これで、アプリケーションがプッシュ通知をサポートするように更新されました。

    func application(application: UIApplication,
        didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
        ClientManager.sharedClient.push?.registerDeviceToken(deviceToken) { error in
            print("Error registering for notifications: ", error?.description)
        }
    }
    
    func application(application: UIApplication,
        didFailToRegisterForRemoteNotificationsWithError error: NSError) {
        print("Failed to register for remote notifications: ", error.description)
    }
    
    func application(application: UIApplication,
        didReceiveRemoteNotification userInfo: [NSObject: AnyObject]) {
    
        print(userInfo)
    
        let apsNotification = userInfo["aps"] as? NSDictionary
        let apsString       = apsNotification?["alert"] as? String
    
        let alert = UIAlertController(title: "Alert", message: apsString, preferredStyle: .Alert)
        let okAction = UIAlertAction(title: "OK", style: .Default) { _ in
            print("OK")
        }
        let cancelAction = UIAlertAction(title: "Cancel", style: .Default) { _ in
            print("Cancel")
        }
    
        alert.addAction(okAction)
        alert.addAction(cancelAction)
    
        var currentViewController = self.window?.rootViewController
        while currentViewController?.presentedViewController != nil {
            currentViewController = currentViewController?.presentedViewController
        }
    
        currentViewController?.presentViewController(alert, animated: true) {}
    
    }
    

プッシュ通知をテストする

  • Xcode で [Run] をクリックし、iOS デバイスでアプリを起動します (シミュレーターではプッシュは機能しません)。 [OK] をクリックしてプッシュ通知を受け入れます。この要求は、アプリの初回実行時に発生します。
  • アプリで新しい項目を追加し、 + をクリックします。
  • 通知が受信されたことを確認し、 [OK] をクリックして通知を破棄します。 これで、このチュートリアルは終了です。

詳細