ガイドとサンプルコード

デベロッパ

LocalおよびPush Notificationプログラミングガイド

このページの内容

リモート通知サポートの設定

リモート通知をサポートすると、アプリケーションが実行されていない間も、アプリケーションのユーザーに最新の情報を届けることができます。リモート通知を受信してハンドルできるようにするには、アプリケーションで以下の処理をおこないます。

  1. リモート通知を有効にする。

  2. Apple Push Notificationサービス(APNs)に登録し、アプリケーション固有のデバイストークンを受け取る。

  3. デバイストークンを通知プロバイダサーバに送信する。

  4. 着信するリモート通知をハンドルするためのサポート機能を実装する。

この章では、アプリケーションにすべて実装することになる、これらの処理について説明します。プロバイダ(通知リクエストを生成してAPNsに送信するために、デベロッパが導入し、管理するサーバ)の詳細については、「APNsの概要」を参照してください。

プッシュ通知機能の有効化

リモート通知をハンドルするアプリケーションは、APNsとやり取りするための適切なエンタイトルメントを保持していなければなりません。このエンタイトルメントをアプリケーションに追加するには、Xcodeプロジェクトの「Capabilities」ペインを使います(Xcodeのヘルプの「Enable push notifications」を参照)。

必要なエンタイトルメントを保持していないアプリケーションは、App Storeのレビュープロセスで拒否されますテストの実施中、適切なエンタイトルメントがないままAPNsに登録しようとすると、エラーが返されます。

リモート通知を受信するための登録

アプリケーションは、起動されるたびにAPNsに登録しなければなりません。APNsへの登録に用いる手法はプラットフォームによって異なりますが、いずれの場合も以下のようになります。

  1. アプリケーションがAPNsへの登録を要求する。

  2. 登録が正常に完了した後、APNsがアプリケーション固有のデバイストークンをデバイスに送信する。

  3. システムが、アプリケーションデリゲートのメソッドを呼び出すことにより、デバイストークンをアプリケーションに配送する。

  4. アプリケーションが、アプリケーションに関連づけられているプロバイダにデバイストークンを送信する。

これらの手順を示したコードの例については、「iOSおよびtvOSでのデバイストークンの取得」および「macOSでのデバイストークンの取得」を参照してください。

アプリケーション固有のデバイストークンはグローバルに一意であり、アプリケーションとデバイスの組み合わせを1つに特定します。APNsから送信されるデバイストークンがアプリケーションで受信された後、プロバイダへのネッワーク接続を開く処理は、デベロッパが記述します。その後、プロバイダに送信したいその他のあらゆる関連データとともにデバイストークンをアプリケーションで転送する処理についても、同様にデベロッパが記述します。後ほど、プロバイダがリモート通知リクエストをAPNsに送信するときは、デバイストークンが通知ペイロードと併せてリクエストに収容されていなければなりません。詳細については、「APNsの概要」を参照してください)。

デバイストークンはアプリケーションにキャッシュせず、必要になった時点でシステムから取得してください。APNsは、一定のイベントが発生した場合、アプリケーションに新しいデバイストークンを発行します。ユーザーがデバイスをバックアップから復元した、ユーザーが新規デバイスにアプリケーションをインストールした、ユーザーがオペレーティングシステムを再インストールしたといった場合、デバイストークンは確実に変化します。キャッシュを利用するのではなく、トークンをフェッチすることによって、プロバイダとAPNsとのやり取りで必要な最新のデバイストークンであることが保証されます。フェッチしようとした時点でデバイストークンが変化していなければ、フェッチメソッドからすぐに結果が返されます。

watchOSで実行されるアプリケーションは、明示的にはリモート通知に登録しません。ペアリング済みのiPhoneを介してリモート通知をApple Watchに転送し、表示します。リモート通知が転送されるのは、iPhoneがロックされていて(または画面がスリープ状態)、Apple Watchがユーザーの腕に装着され、ロックが解除されているときです。

リモート通知のデータ形式およびAPNsへのデータの送信方法については、「APNsとのやり取り」を参照してください。

iOSおよびtvOSでのデバイストークンの取得

iOSおよびtvOSでAPNsへのアプリケーションの登録を開始するには、UIApplicationオブジェクトのregisterForRemoteNotificationsメソッドを呼び出します。アプリケーションの起動時に、通常の起動シーケンスの一環として呼び出してください。アプリケーションがこのメソッドを初めて呼び出したとき、アプリケーションオブジェクトがAPNsにアクセスし、アプリケーション固有のデバイストークンをリクエストします。リクエストの成否に応じて、以下の2つのうち、いずれかのアプリケーションデリゲートメソッドをシステムが非同期で呼び出します。

APNsへの登録が正常に完了した後、アプリケーションオブジェクトがAPNsにアクセスするのは、デバイストークンが変化した場合のみです。変化がなければ、registerForRemoteNotificationsメソッドを呼び出すと、既存のトークンを即座に返すapplication:didRegisterForRemoteNotificationsWithDeviceToken:メソッドが呼び出されます。

リスト4-1に、iOSまたはtvOSでデバイストークンをフェッチする方法を示します。このアプリケーションデリゲートは、通常の起動時設定の一環としてregisterForRemoteNotificationsメソッドを呼び出します。受信したデバイストークンは、application:didRegisterForRemoteNotificationsWithDeviceToken:メソッドがカスタムメソッドを使ってアプリケーションの関連プロバイダに転送します。登録中にエラーが発生した場合、アプリケーションは、リモート通知に関係する機能を一時的にすべて無効にします。それらの機能は、有効なデバイストークンが受信された時点で再び有効になります。

リスト4-1リモート通知を受信するための登録(iOS)

Objective-C

  1. - (void)applicationDidFinishLaunching:(UIApplication *)app {
  2. // ユーザーとのやり取りを最初に設定。
  3. [self configureUserInteractions];
  4. // リモート通知を受け取る旨の登録。
  5. [[UIApplication sharedApplication] registerForRemoteNotifications];
  6. }
  7. // リモート通知の登録処理。
  8. - (void)application:(UIApplication *)app
  9. didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
  10. // カスタムメソッドを使って、トークンをプロバイダに転送。
  11. [self enableRemoteNotificationFeatures];
  12. [self forwardTokenToServer:devTokenBytes];
  13. }
  14. - (void)application:(UIApplication *)app
  15. didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
  16. // トークンは現時点で取得不能。
  17. NSLog(@"Remote notification support is unavailable due to error: %@", err);
  18. [self disableRemoteNotificationFeatures];
  19. }

Swift

  1. func application(_ application: UIApplication,
  2. didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  3. // ユーザーとのやり取りを最初に設定。
  4. self.configureUserInteractions()
  5. // APNsへの登録。
  6. UIApplication.shared.registerForRemoteNotifications()
  7. }
  8. // リモート通知の登録処理。
  9. func application(_ application: UIApplication,
  10. didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data){
  11. // カスタムメソッドを使って、トークンをプロバイダに転送。
  12. self.enableRemoteNotificationFeatures()
  13. self.forwardTokenToServer(token: deviceToken)
  14. }
  15. func application(_ application: UIApplication,
  16. didFailToRegisterForRemoteNotificationsWithError error: Error) {
  17. // トークンは現時点で取得不能。
  18. print("Remote notification support is unavailable due to error: \(error.localizedDescription)")
  19. self.disableRemoteNotificationFeatures()
  20. }

携帯電話接続またはWi-Fi接続が使用できない場合、application:didRegisterForRemoteNotificationsWithDeviceToken:メソッドおよびapplication:didFailToRegisterForRemoteNotificationsWithError:メソッドはどちらも呼び出されません。Wi-Fi接続では、これは、デバイスが所定のポート経由で接続できない場合に発生することがあります。この場合、ユーザーは必要なポートがブロックされていない他のWi-Fiネットワークに移動できます。携帯電話用無線機能を備えたデバイスの場合、ユーザーは、携帯電話データサービスが使用可能になるまで待機することもできます。

application:didFailToRegisterForRemoteNotificationsWithError:の実際の実装では、引数として渡されるエラーオブジェクトを利用して、リモート通知に関係する機能をすべて無効にします。このメソッドが呼び出された場合、いずれにしても通知が届くことはないので、軟着陸させる形で機能を落とし、リモート通知の円滑な実行に必要なローカル処理は避ける方がよいでしょう。その後、リモート通知が使用可能になった場合は、アプリケーションオブジェクトがデリゲートのapplication:didRegisterForRemoteNotificationsWithDeviceToken:メソッドを呼び出して通知します。

macOSでのデバイストークンの取得

macOSでアプリケーションのデバイストークンを取得するには、NSApplicationオブジェクトのregisterForRemoteNotificationTypes:メソッドを呼び出します。アプリケーションの起動時に、通常の起動シーケンスの一環として呼び出すことを推奨します。アプリケーションが最初にこのメソッドを呼び出したときは、アプリケーションオブジェクトがAPNsにトークンをリクエストします。最初の呼び出しの後、アプリケーションオブジェクトがAPNsとやり取りするのは、デバイストークンが変化したときのみであり、変化していない場合は既存のトークンが即時に返されます。

アプリケーションオブジェクトは、デバイストークンの取得が成功したかどうかをデリゲートに対して非同期的に通知します。これらのデリゲートコールバックを使って、デバイストークンを処理したり、発生したエラーをハンドルしたりしてください。登録が正常に完了したかどうかを追跡するには、以下のデリゲートメソッドを実装する必要があります。

リスト4-2に、macOSでデバイストークンをフェッチする方法を示します。アプリケーションデリゲートは、通常の起動時設定の一環としてregisterForRemoteNotificationTypes:メソッドを呼び出し、開発者が利用しようとしているやり取りのタイプを渡します。受信したデバイストークンは、application:didRegisterForRemoteNotificationsWithDeviceToken:メソッドがカスタムメソッドを使ってアプリケーションの関連プロバイダに転送します。登録中にエラーが発生した場合、アプリケーションは、リモート通知に関係する機能を一時的にすべて無効にします。それらの機能は、有効なデバイストークンが受信された時点で再び有効になります。

リスト4-2リモート通知を受信するための登録(macOS)

Objective-C

  1. - (void)applicationDidFinishLaunching:(NSNotification *)notification {
  2. // ユーザーとのやり取りを最初に設定。
  3. [self configureUserInteractions];
  4. [NSApp registerForRemoteNotificationTypes:(NSRemoteNotificationTypeAlert | NSRemoteNotificationTypeSound)];
  5. }
  6. - (void)application:(NSApplication *)application
  7. didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  8. // カスタムメソッドを使って、トークンをプロバイダに転送。
  9. [self forwardTokenToServer:deviceToken];
  10. }
  11. - (void)application:(NSApplication *)application
  12. didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
  13. NSLog(@"Remote notification support is unavailable due to error: %@", error);
  14. [self disableRemoteNotificationFeatures];
  15. }

Swift

  1. func applicationDidFinishLaunching(_ aNotification: Notification) {
  2. // ユーザーとのやり取りを最初に設定。
  3. self.configureUserInteractions()
  4. NSApplication.shared().registerForRemoteNotifications(matching: [.alert, .sound])
  5. }
  6. // リモート通知の登録処理。
  7. func application(_ application: NSApplication,
  8. didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
  9. // カスタムメソッドを使って、トークンをプロバイダに転送。
  10. self.forwardTokenToServer(token: deviceToken)
  11. }
  12. func application(_ application: NSApplication,
  13. didFailToRegisterForRemoteNotificationsWithError error: Error) {
  14. // トークンは現時点で取得不能。
  15. print("Remote notification support is unavailable due to error: \(error.localizedDescription)")
  16. }

Remote Notificationのハンドル

ユーザー通知フレームワークは、iOS、watchOS、tvOSのアプリケーションで使う統一的なAPIを提供するもので、ローカル通知とリモート通知に関係するタスクのほとんどに対応しています。以下に、このフレームワークを使って実行できるタスクの例を挙げます。

  • アプリケーションがフォラグラウンドにある場合は、通知を直接受信することも、無言にすることもできます。

  • アプリケーションがバックグラウンドにある場合または実行されていない場合は、以下のとおりです。

    • 通知に関連づけられているカスタムアクションをユーザーが選択したとき、レスポンスを返すことができます。

    • ユーザーが通知を閉じたときまたはアプリケーションを起動したとき、レスポンスを返すことができます。

アプリケーションは、自身のアプリケーションデリゲートを通じてリモート通知のペイロードを受信します。リモート通知が着信すると、アプリケーションがバックグラウンドにある場合、システムはユーザーとのやり取りを通常どおりハンドルします。iOSとtvOSでは、システムは通知ペイロードをアプリケーションデリゲートのapplication:didReceiveRemoteNotification:fetchCompletionHandler:メソッドに配送します。macOSの場合、ペイロードの配送先は、アプリケーションデリゲートのapplication:didReceiveRemoteNotification:メソッドになります。これらのメソッドを使ってペイロードを確認し、関連タスクを実行することができます。たとえば、バックグラウンド更新通知を受信した後、アプリケーションの新着コンテンツのダウンロードを開始できます。

ユーザー通知フレームワークのメソッドを使って通知をハンドルする方法については、「通知の配信へのレスポンス」を参照してください。アプリケーションデリゲートで通知をハンドルする方法については、『UIApplicationDelegate Protocol Reference』または『NSApplicationDelegate Protocol Reference』を参照してください。