【Swift/Apple Watch】ローカル通知機能の実装方法!フォアグラウンド

この記事からわかること

  • Swift/Apple Watchアプリローカル通知実装する方法
  • UNUserNotificationCenter通知発行するには?
  • フォアグラウンドの際に通知を表示させるには?
  • iPhone(iOS)連携アプリでの通知の表示検証

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

【Swift/Apple Watch】ローカル通知機能の実装方法!フォアグラウンド

Apple Watchアプリでローカル通知を実装する方法

watchOSアプリでローカル通知を実装するにはiOS側での実装と同じくUNUserNotificationCenterを使用します。詳細な実装方法は以下の記事を参考にしてください。

Watch側ではUserNotificationsimportしないとUNUserNotificationCenterクラスが使用できないので注意してください。今回はアプリがフォアグラウンドでも表示されるようにUNUserNotificationCenterDelegateに準拠させています。

import UserNotifications

class NotificationManager: NSObject, UNUserNotificationCenterDelegate {
    
    static let shared = NotificationManager()
    
    private override init() {
        super.init()
        // フォアグラウンドでも通知が表示されるようにする
        UNUserNotificationCenter.current().delegate = self
        requestAuthorization()
    }
    
    private func requestAuthorization() {
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: .alert) { granted, error in
            if granted {
                print("許可されました!")
            }else{
                print("拒否されました...")
            }
        }
    }
    
    func scheduleNotification() {
        let content = UNMutableNotificationContent()
        content.title = "通知のタイトル"
        content.body = "通知の本文"

        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false)
        let request = UNNotificationRequest(identifier: "uniqueIdentifier", content: content, trigger: trigger)
        UNUserNotificationCenter.current().add(request)
    }
    
    // 通知が表示される際に呼ばれるデリゲートメソッド
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.banner, .sound, .badge])
    }
}

あとはUI側で以下のように組み込めばOKです。

struct ContentView: View {

    private let notificationManager = NotificationManager.shared

    var body: some View {
        Button {
            notificationManager.scheduleNotification()
        } label: {
            Text("Watch Notify")
        }
    }
}

フィジビリティ

今回はボタン押下後、3秒後に通知が届くように実装しましたが、シミュレーターで動作を確認してみると3秒で届く時もあれば15秒ほどかかる時もある感じで少し不安定な感じでした。

【Swift/Apple Watch】ローカル通知機能の実装方法!フォアグラウンド

アプリがフォアグラウンドかバックグラウンドの際は上記のような通知ですが、Apple Watch自体がロックされている場合は以下のような通知になります。

【Swift/Apple Watch】ローカル通知機能の実装方法!フォアグラウンド

もちろん通知をタップするとアプリが起動します。

通知をタップされたことを検知する

通知がタップされてアプリが起動した際に任意の処理を実行したい場合UNUserNotificationCenterDelegateの以下のuserNotificationCenter(_:, didReceive : UNNotificationResponse, withCompletionHandler : @escaping () -> Void)が呼ばれるのでこの中に処理を実装します。

func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    didReceive response: UNNotificationResponse,
    withCompletionHandler completionHandler: @escaping () -> Void) {
      print("通知をタップされたよ")
      completionHandler()
}

iPhone(iOS)連携アプリの場合の通知の動き

watchOSアプリがiPhoneと連携しているアプリの場合は通知がどこで発行されるかが異なってきます。基本的には連携している場合はiOS側にローカル通知イベントを仕込んでおき、発火させるとiOS側だけでなくWatch側にもリンクして通知が届きます。

シミュレーターで操作確認をしてみましたが、以下のような感じになりました。基本的に設定された通知は連携している両方のOSへ通知されるようです。しかし両方届かない場合はありませんでしたがiOS側が届かなかったり、Watch側が届かなかったりしたのでここら辺は注意が必要かもしれません。

Watch(アクティブ)
App:フォアグラウンド
Watch(アクティブ)
App:バックグラウンド
Watch(非アクティブ)
App:バックグラウンド
iOS(アクティブ)
App:フォアグラウンド
両方に通知 両方に通知 両方に通知
iOS(アクティブ)
App:バックグラウンド
両方に通知 両方に通知 両方に通知
iOS(非アクティブ)
App:バックグラウンド
両方に通知 両方に通知 両方に通知

※アクティブはロックされていない状態、非アクティブはデバイスがロックされている状態

色々と調べたり、調査をしてみたところ、通知は基本的にアクティブになっているデバイスに届くと公式に記述されていました。シミュレーターや実機で確認したみた際は上記のような挙動になったのも事実なので不安定な部分が大きいようです。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index