ユーザーアクションのハンドラー

ユーザーアクションのハンドラーは、主にユーザーが通知センターのメッセージをタップしたときに呼び出されます。

このハンドラーは、iOS 10 以降と iOS 8/iOS 9 で実装方法や起動のタイミングが異なります。それぞれ下記のセクションで詳細を説明します。各バージョンの iOS をサポートする場合は、両方のメソッドを実装する必要があります。

アクションの使用あり アクションの使用なし
アクションをタップして起動 通知本体をタップして起動 通知本体をタップして起動
iOS 10 iOS 10 以降でのハンドラー で処理
iOS 8/iOS 9 iOS 8/iOS 9 でのハンドラー で処理 プッシュ通知の受信ハンドラー で処理

呼び出しタイミングなどの詳細は、受信メソッドの組み合わせ を参照してください。

なお、通知センターを使用しない場合、ユーザーアクションのハンドラーを用意せず、プッシュ通知の受信ハンドラー だけで機能を実現できます。例えば、サーバー側の KiiObject の変化をプッシュ通知によってモバイルアプリに自動反映したいようなケースでは、モバイルアプリ起動時に KiiObject のフルアップデートを実行し、差分はサイレント通知でアップデートするだけで機能が実現できる場合があります。

iOS 10 以降でのハンドラー

iOS 10 では、userNotificationCenter(_:didReceive:withCompletionHandler:) メソッドによって通知センターのタップ操作を処理します。

このメソッドは、カテゴリーやアクションの操作の有無にかかわらず、ユーザーが通知センターのメッセージをタップしたタイミングで呼び出されます。iOS 10 以降でのハンドラーの場合は、アクションを伴わない、メッセージ本体のタップだけのケースでも呼び出される点にご注意ください。

ハンドラーの実装例を以下に示します。

Swift 3:

// For iOS 10
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
  if (!(response.notification.request.trigger is UNPushNotificationTrigger)) {
    // The received notification is local.
    completionHandler();
    return
  }

  // Check the identifier of the action.
  let identifier = response.actionIdentifier
  print("Selected action: \(identifier)")

  let aps = userInfo["aps"] as? [AnyHashable: Any]
  if let category = aps?["category"] as? String?, category == "MESSAGE_CATEGORY" {
    if identifier == "ACCEPT_IDENTIFIER" {
      print("The user selected ACCEPT_IDENTIFIER.")
    } else if identifier == "DECLINE_IDENTIFIER" {
      print("The user selected DECLINE_IDENTIFIER.")
    }
  }

  // Check the payload of the push message.
  let userInfo = response.notification.request.content.userInfo;
  print("Payload: \(userInfo)")
  let message = KiiReceivedMessage(fromAPNS: userInfo)
  // Do something.

  completionHandler()
}

Objective-C:

// For iOS 10
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(nonnull void (^)())completionHandler {
  if (![response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
    // The received notification is local.
    completionHandler();
    return;
  }

  // Check the identifier of the action.
  NSString *identifier = response.actionIdentifier;
  NSLog(@"Selected action: %@", response.actionIdentifier);

  NSDictionary *aps = userInfo[@"aps"];
  if ([aps[@"category"] isEqualToString:@"MESSAGE_CATEGORY"]) {
    if ([identifier isEqualToString:@"ACCEPT_IDENTIFIER"]) {
      NSLog(@"The user selected ACCEPT_IDENTIFIER.");
    } else if ([identifier isEqualToString:@"DECLINE_IDENTIFIER"]) {
      NSLog(@"The user selected DECLINE_IDENTIFIER.");
    }
  }

  // Check the payload of the push message.
  NSDictionary *userInfo = response.notification.request.content.userInfo;
  NSLog(@"Payload: %@", userInfo);
  KiiReceivedMessage *message = [KiiReceivedMessage messageFromAPNS:userInfo];
  // Do something.

  completionHandler();
}

このメソッドは、プッシュ通知の初期化 の際、iOS 10 以降対応の UNUserNotificationCenter クラスを使って初期化した場合に呼び出されます。なお、iOS 10 でも、UIUserNotificationSettings クラス(非推奨)を使って初期化した場合は、iOS 8/iOS 9 のハンドラー が呼び出され、呼び出しルールも iOS 8/iOS 9 相当になります。

ここでは以下の処理を行っています。

  1. リモート通知(プッシュ通知)であることの確認

    このメソッドはリモート通知とローカル通知で共有されます。まずは、trigger プロパティが、リモート通知を表す UNPushNotificationTrigger インスタンスであることを確認し、処理を進めます。

  2. アクションを確認

    ユーザーが選択したアクションの識別子を変数 identifier に取得して確認します。

    例えば、アクション付きプッシュ通知の初期化 のサンプルコードで初期化した場合、ユーザーが選択したアクションに応じて ACCEPT_IDENTIFIERDECLINE_IDENTIFIER のような文字列が格納されます。また、プッシュメッセージ本体をタップした場合のように、アクションが定まらない場合は、com.apple.UNNotificationDefaultActionIdentifier という文字列が設定されます。

  3. ペイロードを確認

    プッシュメッセージのペイロードを変数 userInfo に取得します。プッシュ通知の受信ハンドラー と同様、これを Kii Cloud の KiiReceivedMessage クラスに渡すと、ペイロードの情報を取得できます。

    コメント // Do something. の箇所で KiiReceivedMessage インスタンスを参照し、Kii Cloud の機能を使った処理を実行します。KiiReceivedMessage クラスの使用方法は、サーバー上変更のプッシュ通知(Push to App)ユーザープッシュ通知 (Push to User)管理者メッセージのプッシュ通知(Direct Push) を参照してください。

  4. 処理の完了

    処理の最後に completionHandler ブロックを呼び出します。

なお、userNotificationCenter(_:didReceive:withCompletionHandler:) メソッドは、UNUserNotificationCenterDelegate プロトコルのメソッドであるため、初期化の例 に示すようにクラス宣言の修正が必要です。また、アクション追記プッシュ通知の初期化 のサンプルコードで実行しているように、UNUserNotificationCenterdelegate プロパティを設定しておく必要があります。

フォアグラウンドでのアクション表示

iOS 10 以降では、モバイルアプリがフォアグラウンドで動作している間も、通知センターにプッシュメッセージを表示し、アクションを選択させることができます。

フォアグラウンドで動作中、通知センターにメッセージを表示するには、userNotificationCenter(_:willPresent:withCompletionHandler:) メソッドを実装します。メソッドが実装されていない場合は、通知が表示されない動きです。このメソッドをカスタマイズする方法は iOS の API リファレンスを検索してください。

iOS 8/iOS 9 でのハンドラー

iOS 8/iOS 9 では、application(_:handleActionWithIdentifier:forRemoteNotification:withResponseInfo:completionHandler:) メソッドによって通知センターのプッシュメッセージのアクションがタップされた際のイベントを処理します。

iOS 10 の場合と異なり、このメソッドでは、カテゴリーのアクションがタップされた場合のイベントのみが処理されます。

ハンドラーの実装例を以下に示します。

Swift 3:

// For iOS 8/9
func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [AnyHashable: Any], completionHandler: @escaping () -> Void){
  print("Payload: \(userInfo)")
  print("Selected action: \(identifier)")

  // Check the identifier of the action.
  let aps = userInfo["aps"] as? [AnyHashable: Any]
  if let category = aps?["category"] as? String?, category == "MESSAGE_CATEGORY" {
      if identifier == "ACCEPT_IDENTIFIER" {
          print("User selected ACCEPT_IDENTIFIER")
      } else if identifier == "DECLINE_IDENTIFIER" {
          print("User selected DECLINE_IDENTIFIER")
      }
  }

  // Check the payload of the push message.
  let message = KiiReceivedMessage(fromAPNS: userInfo)
  // Do something.

  completionHandler()
}

Objective-C:

// For iOS 8/9
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler {
  NSLog(@"Payload: %@", userInfo);
  NSLog(@"Selected action: %@", identifier);

  // Check the identifier of the action.
  NSDictionary *aps = userInfo[@"aps"];
  if ([aps[@"category"] isEqualToString:@"MESSAGE_CATEGORY"]) {
    if ([identifier isEqualToString:@"ACCEPT_IDENTIFIER"]) {
      NSLog(@"The user selected ACCEPT_IDENTIFIER.");
    } else if ([identifier isEqualToString:@"DECLINE_IDENTIFIER"]) {
      NSLog(@"The user selected DECLINE_IDENTIFIER.");
    }
  }

  // Check the payload of the push message.
  KiiReceivedMessage *message = [KiiReceivedMessage messageFromAPNS:userInfo];
  // Do something.

  completionHandler();
}

ここでは以下の処理を行っています。

  1. アクションを確認

    ユーザーが選択したアクションの識別子は identifier で確認できます。

    例えば、アクション付きプッシュ通知の初期化 のサンプルコードで初期化した場合、ユーザーが選択したアクションに応じて ACCEPT_IDENTIFIERDECLINE_IDENTIFIER のような文字列が格納されます。

  2. ペイロードを確認

    プッシュメッセージのペイロードは userInfo で確認できます。プッシュ通知の受信ハンドラー と同様、これを Kii Cloud の KiiReceivedMessage クラスに渡すと、ペイロードの情報を取得できます。

    コメント // Do something. の箇所で KiiReceivedMessage インスタンスを参照し、Kii Cloud の機能を使った処理を実行します。KiiReceivedMessage クラスの使用方法は、サーバー上変更のプッシュ通知(Push to App)ユーザープッシュ通知 (Push to User)管理者メッセージのプッシュ通知(Direct Push) を参照してください。

  3. 処理の完了

    処理の最後に completionHandler ブロックを呼び出します。