CrossBridge Lab

技術ネタ、デバイスネタを...

User Notifications Frameworkを使用してカスタム通知アクション付きのプッシュ通知を送る

カスタム通知アクションとは

 iOS8から追加されたもので、通知(Local Notification と Remote Notification)にボタンを追加してユーザーに何かしらの選択をさせる機能です。

f:id:crossbridge-lab:20161025113947p:plain

iOS10でカスタム通知アクションを使う

 iOS10からUser Notifications Frameworkが追加され、通知周りの処理はこのフレームワークを使うようになっています。iOS10でカスタム通知を使う流れは以下のとおりです。

  1. UNNotificationActionを作成する
  2. 作成したUNNotificationActionを指定して、UNNotificationCategoryを作成する
  3. 作成したUNNotificationCategoryUNUserNotificationCenterに設定する
  4. カスタム通知アクションを選択されたときの処理を記述する
  5. カテゴリを指定したリモート通知またはローカル通知を送る

それぞれ見ていきましょう。サンプルはSwift3で書いています。

1. UNNotificationActionを作成する

 まずは1例を。(UserNotificationsのimportも忘れずに)

let okAction = UNNotificationAction(identifier:"action_ok",
                                    title: "OK",
                                    options: [.foreground])
let ngAction = UNNotificationAction(identifier: "action_ng",
                                    title: "NG",
                                    options: [.destructive, .foreground])

 引数は以下のとおりです。

  • identifier:アクションの識別子。ユーザーがどのアクションを選択したのかを判別するために使う
  • title:名前の通りタイトル。通知に表示されるボタンに表示される。
  • options:authenticationRequired、destructive、foregroundが指定可能。詳細は後述。

 optionsにはUNNotificationActionOptionsをセットします。UNNotificationActionOptionsには3つの値が用意されており、それぞれセットすると以下の挙動になります。

内容
authenticationRequired ロックを解除しないとアクションを選択できない
destructive 破壊的な処理の場合に設定する。通知にされるアクション用のボタンのテキストが赤色になる
foreground アクションを選択した時にアプリがフォアグラウンドで起動する

2. UNNotificationCategoryを作成する

 次にUNNotificationActionを指定してUNNotificationCategoryを作成します。通知が届いたらその通知のカテゴリに応じたアクションが表示されることになります。先程作成した2つのActionを指定したUNNotificationCategoryを作成します。

let category = UNNotificationCategory(identifier: "category_select",
                                      actions: [okAction, ngAction],
                                      intentIdentifiers: [],
                                      options: [])
  • identifier:カテゴリの識別子。
  • actions:通知の表示させたいアクション。
  • intentIdentifiers:Intentの識別子。
  • options:customDismissActionとallowInCarPlayが指定可能。それぞれ通知を削除したときのイベントをハンドリングできるようにするため、CarPlay環境で通知を表示するためのもの。

3. UNUserNotificationCenterに設定する

 UNNotificationCategoryを作成したらUNUserNotificationCenterの`setNotificationCategories(_:)メソッドで設定します。

let center = UNUserNotificationCenter.current()
center.setNotificationCategories([category])
center.delegate = self
center.requestAuthorization(options: [.alert, .badge, .sound]) {
    if $0.0 {
        let application = UIApplication.shared
        application.registerForRemoteNotifications()
    }
}

4. カスタム通知アクションを選択されたときの処理を記述する

 通常のプッシュ通知と同じようにUNUserNotificationCenterDelegateのuserNotificationCenter(_:didReceiveNotificationResponse:withCompletionHandler:)メソッドが呼ばれます。response.actionIdentifierでどのアクションを選択したのか分かるため、必要な処理を実行させるようにします。

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Swift.Void) {
    
    switch response.actionIdentifier {
    case "action_ok":
        break
    case "action_NG":
        break
    default:    // アクションではなく通知自体をタップしたときは UNNotificationDefaultActionIdentifier が渡ってくる
        break
    }
    
    completionHandler()
}

5. カテゴリを指定したリモート通知またはローカル通知を送る

 リモート通知の場合はペイロードcategoryを追加します。

category: "category_select"

 ローカル通知の場合はUNMutableNotificationContentcategoryIdentifierプロパティに設定します。

let content = UNMutableNotificationContent()
content.title = "通知テスト"
content.body = "OK or NG?"
content.sound = UNNotificationSound.default()
content.categoryIdentifier = "category_select"

let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 5, repeats: false)
let request = UNNotificationRequest.init(identifier: "testPush", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request)

まとめ

 以下の流れですでに通知機能を実装していればUNNotificationActionとてUNNotificationCategoryを使ってカスタム通知に対応するのはそんなに労力は必要ないかと思います。

  1. UNNotificationActionを作成する
  2. 作成したUNNotificationActionを指定して、UNNotificationCategoryを作成する
  3. 作成したUNNotificationCategoryUNUserNotificationCenterに設定する
  4. カスタム通知アクションを選択されたときの処理を記述する
  5. カテゴリを指定したリモート通知またはローカル通知を送る