【Swift】ローカル通知が受信されたかを知る方法
どうも、ねこきち(@nekokichi1_yos2)です。
今回は、ローカル通知の受信を検知する方法を載せます。
ローカル通知のデリゲートメソッドについて
ローカル通知には、
- willPresent()
- didReceive()
のデリゲートメソッドしかありません。
しかも、上記の2つはそれぞれ、
- フォアグラウンドで通知を受け取った時
- 通知をタップした時
でしか実行されません。
もし、ユーザーがアプリをタップした場合、デリゲートメソッドに引っかからず、アプリを起動した時、通知が受信された時に実行したい処理がスルーされてしまいます。
(プッシュ通知なら、受信時の処理を実行できるだろうが、今回は却下。)
そこで登場するのが、getDeliverdNotification()、です
getDeliverdNotification()を使う
ドキュメントでは、NotificationCenterに登録された通知の一覧を返すメソッド、だそうです。
書き方は、以下の通り。
↓
UNUserNotificationCenter.current().getDeliveredNotifications { (notification) in
}
クロージャの引数をprint()で出力すると、受信された通知の詳細が出ます。
↓
また、取得する値は、UNNotification型の配列です。
↓
例えば、配列のプロパティであるisEmptyを利用すれば、
- true:受信されてない
- false:受信された
により、通知が受信された時の処理を実装できます。
↓
UNUserNotificationCenter.current().getDeliveredNotifications { (notification) in if notification.isEmpty { // 受信してない } else { // 受信した } }
結果、ローカル通知のデリゲートメソッドでは拾えなかった、
- アプリをタップ
- マルチタスク画面でアプリをタップ
のユーザーアクションにも対応できます。
getDeliverdNotification()でできること
まとめると、
- ローカル通知の詳細を取得できる
- ローカル通知が受信されたかがわかる
- sceneDidBecomeActive()と併用すれば、アプリの直接起動でも、受信状態の分岐ができる
ソースコード
import UIKit class UNUserNotificationTest: UIViewController { override func viewDidLoad() { super.viewDidLoad() let content = UNMutableNotificationContent() content.title = "通知" content.body = "受信しました" content.sound = .default // 5秒後に通知 let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false) let request = UNNotificationRequest(identifier: "notification", content: content, trigger: trigger) let center = UNUserNotificationCenter.current() center.add(request) { (error) in if let error = error { print(error) } } } } import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { //ローカル通知 UNUserNotificationCenter.current().requestAuthorization( options: [.alert, .sound, .badge]){ (granted, _) in if granted{ UNUserNotificationCenter.current().delegate = self } } return true } } import UIKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let _ = (scene as? UIWindowScene) else { return } } // バックグラウンド -> フォアグラウンド、で実行 func sceneDidBecomeActive(_ scene: UIScene) { UNUserNotificationCenter.current().getDeliveredNotifications { (notification) in if notification.isEmpty { // 受信してない } else { // 受信した print("受信しました") } } } }