2024-03-15
続きです。通知通信のための証明書作成・登録はテスト・本番用それぞれ前回で終えたので、あとは段階を踏んで実装・テストするだけです。
Firebase SDKにてCloud Messagingの使用をオンにする
Podfileに追記します。
pod 'FirebaseMessaging'
アップデート&インストールします。
pod install --repo-update
これでソース中でimport FirebaseMessagingとして、コードを書けるようになるはずです。
CapabilityにPush NotificationsとBackground Modesを追加する
Xcodeでプロジェクト(xcworkspace)を開いて、左ペイン一番上プロジェクト名青アイコン→TARGETS→MyAppで、「Signing & Capabilities」を開きます。
気づきにくいですが左上あたりに「+Capability」があるので、ここで「Push Notifications」と「Background Modes」をそれぞれ追加します。そして「Background Modes」には、「Remote notifications」をチェックします。
プッシュ通知に対応するSwiftコードを書く
基本的にはAppDelegate.swiftに書きますが、ユーザーに通知の許可をもらうダイアログはアプリの他の適切な箇所のほうが良いです。
Swift | AppDelegatePushNotify.swift | GitHub Source |
import SwiftUI import FirebaseCore import FirebaseMessaging import UserNotifications class AppDelegate: NSObject, UIApplicationDelegate { let gcmMessageIDKey = "gcm.message_id" func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { print("AppDelegate.application") FirebaseApp.configure() Messaging.messaging().delegate = self UNUserNotificationCenter.current().delegate = self let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound] UNUserNotificationCenter.current().requestAuthorization( options: authOptions, completionHandler: { _, _ in } ) application.registerForRemoteNotifications() //application.applicationIconBadgeNumber = 0 return true } func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) { print("AppDelegate.didReceiveRemoteNotification") if let messageID = userInfo[gcmMessageIDKey] { print("Message ID: \(messageID)") } print(userInfo) } func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) async -> UIBackgroundFetchResult { print("AppDelegate.didReceiveRemoteNotificationBackground") if let messageID = userInfo[gcmMessageIDKey] { print("Message ID: \(messageID)") } print(userInfo) return UIBackgroundFetchResult.newData } func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print("AppDelegate.didFailToRegisterForRemoteNotificationsWithError,error=\(error.localizedDescription)") } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { print("AppDelegate.didRegisterForRemoteNotificationsWithDeviceToken,deviceToken=\(deviceToken)") } } // [START ios_10_message_handling] extension AppDelegate: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification) async -> UNNotificationPresentationOptions { print("AppDelegate.UNUserNotificationCenterDelegate.willPresent") let userInfo = notification.request.content.userInfo if let messageID = userInfo[gcmMessageIDKey] { print("Message ID: \(messageID)") } print(userInfo) return [[.banner, .badge, .sound]] } func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async { print("AppDelegate.UNUserNotificationCenterDelegate.didReceive") let userInfo = response.notification.request.content.userInfo if let messageID = userInfo[gcmMessageIDKey] { print("Message ID: \(messageID)") } print(userInfo) } } // [END ios_10_message_handling] extension AppDelegate: MessagingDelegate { func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) { print("AppDelegate.MessagingDelegate.didReceiveRegistrationToken,fcmToken=\(String(describing: fcmToken))") let dataDict: [String: String] = ["token": fcmToken ?? ""] NotificationCenter.default.post( name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict ) } } @main struct MyApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var body: some Scene { WindowGroup { ContentView() } } }
ここではアプリ起動時にrequestAuthorizationしてユーザーに許可を促しています。
テストデバイストークンを取得してコピーしておく
このコードでアプリを実行すると、
print("AppDelegate.didRegisterForRemoteNotificationsWithDeviceToken,deviceToken=\(deviceToken)")
または
print("AppDelegate.MessagingDelegate.didReceiveRegistrationToken,fcmToken=\(String(describing: fcmToken))")
が呼ばれてそのデバイスのトークン文字列がデバッグエリアに出力されますので、それをコピーしておきます。
Firebase Messagingでテストメッセージを送信する
Firebaseコンソールを開いて、左ペインの「Messaging」を開き、Messagingのメイン画面にて「新しいキャンペーンを作成→通知」を開きます。
・端末上に表示される通知のタイトル、通知テキスト(本文)を入力します。
・「ターゲット」で、通知を送信するターゲットアプリを選択します。jp.co.mycorp.MyApp。
・「スケジュール設定」は今すぐ送信「現在」
・「その他のオプション」で通知音の有無、バッジの有無と数を指定できます。バッジありで数を指定した場合、アプリ側のアイコンの右上に未読の数が赤丸で出るあれです。
ここまで設定を終えたら「確認」ボタンを押さずに、「通知」に戻って「テスト メッセージの送信」を押します。ここで、「FCM 登録トークンを追加」とあるので、さきほど控えておいたデバイスのトークン文字列を貼り付けて登録し、チェックで選択して、「テスト」ボタンを押すと、即座に実行中のデバイス単体に通知が送信されます。
通知をタップすれば上記コードのAppDelegate.UNUserNotificationCenterDelegate.didReceiveが呼ばれますし、アプリが実行中で表示中であればAppDelegate.UNUserNotificationCenterDelegate.willPresentが呼ばれるはずです。そうなれば成功です。
※本記事内容の無断転載を禁じます。
ご連絡は以下アドレスまでお願いします★
☆ServerNote.NETショッピング↓
ShoppingNote / Amazon.co.jp
☆お仲間ブログ↓
一人社長の不動産業務日誌
【Git】特定ファイルを除外する.gitignore
【Ubuntu/Debian】NVIDIA関係のドライバを自動アップデートさせない
【Python】Spacyを使用して文章から出発地と目的地を抜き出す
HomeBrewでApache2を入れて自動起動つきで動かしPHPモジュールと連携する
macOSに標準付属のApacheを自動起動つきで動かす
HomeBrewでPostgreSQLを入れて自動起動つきで動かす
Windows11でSSHポートフォワードでSamba(139)ポートをbindできないエラー
システムで予約済みのパーティションを更新できませんでした このPCは現在Windows11のシステム要件を満たしていません
ソースからインストールしたPHPにPDO版MySQLとPostgreSQLを組み込む
【Windows10】リモートデスクトップ間のコピー&ペーストができなくなった場合の対処法
Windows版Google Driveが使用中と言われアンインストールできない場合
【C/C++】小数点以下の切り捨て・切り上げ・四捨五入
Windows11+WSL2でUbuntuを使う【2】ブリッジ接続+固定IPの設定
LinuxからWindowsの共有フォルダをマウントする
【MinGW】Windowsでgcc/g++コンパイラを使って開発する
【Apache】サーバーに同時接続可能なクライアント数を調整する
Googleスプレッドシートを編集したら自動で更新日時を入れる
VirtualBoxの仮想マシンをWindows起動時に自動起動し終了時に自動サスペンドする