2024-03-15




FirebaseでiOSアプリにプッシュ通知機能を実装する【1】
続きです。通知通信のための証明書作成・登録はテスト・本番用それぞれ前回で終えたので、あとは段階を踏んで実装・テストするだけです。
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が呼ばれるはずです。そうなれば成功です。
※本記事内容の無断転載を禁じます。
ご連絡は以下アドレスまでお願いします★
オープンソースリップシンクエンジンSadTalkerをDebianで動かす
ファイアウォール内部のOpenAPI/FastAPIのdocsを外部からProxyPassで呼ぶ
Debian 12でsshからshutdown -h nowしても電源が切れない場合
【Windows&Mac】アプリのフルスクリーンを解除する方法
Debian 12でtsコマンドが見つからないcommand not found
Debian 12でsyslogやauth.logが出力されない場合
Debian 12で固定IPアドレスを使う設定をする
Debian 12 bookwormでNVIDIA RTX4060Ti-OC16GBを動かす
【Debian】apt updateでCD-ROMがどうのこうの言われエラーになる場合
【Windows10】リモートデスクトップ間のコピー&ペーストができなくなった場合の対処法
Windows11+WSL2でUbuntuを使う【2】ブリッジ接続+固定IPの設定
GitLabにHTTPS経由でリポジトリをクローン&読み書きを行う
【C/C++】小数点以下の切り捨て・切り上げ・四捨五入
Intel Macbook2020にBootCampで入れたWindows11 Pro 23H2のBluetoothを復活させる
【Apache】サーバーに同時接続可能なクライアント数を調整する
【ひかり電話+VoIPアダプタ】LANしか通ってない環境でアナログ電話とFAXを使う
【Debian】apt updateでCD-ROMがどうのこうの言われエラーになる場合
DebianにウェブサーバーApache2をセットアップ