[iOS 10] 画面上部または通知センター上に表示された通知がタップされたときの処理を実装する
はじめに
こんにちは。モバイルアプリサービス部の平屋です。前回の記事に引き続き、iOS 10 で追加された「User Notifications framework」のクラスを使用した実装を紹介します。
本記事では、画面上部または通知センター上に表示された通知がタップされたときの処理の実装を紹介します。
本記事は Apple からベータ版として公開されているドキュメントを情報源としています。 そのため、正式版と異なる情報になる可能性があります。ご留意の上、お読みください。
実装
deprecated になったメソッドについて
iOS 9 以前の場合、UIApplicationDelegate
の以下の 2 つのメソッドを使用していましたが、iOS 10 で deprecated になりました。
optional public func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) optional public func application(_ application: UIApplication, didReceive notification: UILocalNotification)
上記のメソッドの代わりになるメソッドが UNUserNotificationCenterDelegate
に用意されているので、そのメソッドの使い方を解説していきます。
通知がタップされたときの処理を実装
任意のオブジェクトを UNUserNotificationCenter
のデリゲートにして、userNotificationCenter(_:didReceive:withCompletionHandler:)
メソッドを実装します。
// デリゲートを設定 UNUserNotificationCenter.current().delegate = self
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) { // 通知の情報を取得 let notification = response.notification // リモート通知かローカル通知かを判別 if notification.request.trigger is UNPushNotificationTrigger { print("didReceive Push Notification") } else { print("didReceive Local Notification") } // 通知の ID を取得 print("notification.request.identifier: \(notification.request.identifier)") // 処理完了時に呼ぶ completionHandler() }
response
引数から、UNNotification
を取れるので、リモート通知かローカル通知かを判別することができます。
また、UNNotification
は UNNotificationRequest
をプロパティに持つので、通知の ID からどの通知がタップされたかを判別することができます。
completionHandler
userNotificationCenter(_:didReceive:withCompletionHandler:)
メソッドの 3 つ目の引数 completionHandler
について、リファレンスを読むと「You must execute this block from your method, and should call it as quickly as possible. 」と書いてありました。
メソッド内の処理の最後に completionHandler()
を呼ぶようにします。呼ばないとどうなるかをためしてみると、warning のログがコンソールに表示されました。
Warning: UNUserNotificationCenter delegate received call to -userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: but the completion handler was never called.
アプリがメモリ上にあるかどうかによる違い
通知がタップされた時に、アプリがメモリ上にある場合でもない場合でも、userNotificationCenter(_:didReceive:withCompletionHandler:)
メソッドを使用して、通知がタップされたときのイベントを取得できます。
しかし、アプリがメモリ上にない状態で通知がタップされたイベントを取得したい場合は、UNUserNotificationCenter
のデリゲートを割り当てるタイミングをよく考える必要がありそうです。
試しに、AppDelegate
を didFinishLaunchingWithOptions
メソッド内で UNUserNotificationCenter
のデリゲートにして、AppDelegate
にデリゲートメソッドを実装したところ、上手くいきました。
さいごに
本記事では、画面上部または通知センター上に表示された通知がタップされたときの処理を実装を紹介しました。
「通知がタップされたときに特定の画面に遷移させる」といった仕様を実現する時に必須の実装になりますね。通知がリモートかローカルかによらず、同じメソッドでハンドリングできるのは良いなと思いました。
今後も User Notifications framework のクラスを試していきます!