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が呼ばれるはずです。そうなれば成功です。
※本記事内容の無断転載を禁じます。
ご連絡は以下アドレスまでお願いします★
Wav2Lipのオープンソース版を改造して外部から呼べるAPI化する
Wav2Lipのオープンソース版で静止画の口元のみを動かして喋らせる
【iOS】アプリアイコン・ロゴ画像の作成・設定方法
オープンソースリップシンクエンジンSadTalkerをAPI化してアプリから呼ぶ【2】
オープンソースリップシンクエンジンSadTalkerをAPI化してアプリから呼ぶ【1】
【Xcode】iPhone is not available because it is unpairedの対処法
【Let's Encrypt】Failed authorization procedure 503の対処法
【Debian】古いバージョンでapt updateしたら404 not foundでエラーになる場合
ファイアウォール内部のWindows11 PCにmacOS Sequoiaからリモートデスクトップする
Windows11+WSL2でUbuntuを使う【2】ブリッジ接続+固定IPの設定
進研ゼミチャレンジタッチをAndroid端末化する
VirtualBoxの仮想マシンをWindows起動時に自動起動し終了時に自動サスペンドする
Windows11のコマンドプロンプトでテキストをコピーする
Androidホームで左にスワイプすると出てくるニュース共を一切表示させない方法
Googleスプレッドシートを編集したら自動で更新日時を入れる
Node.jsからPostgreSQLサーバに接続・操作する
【Apache】サーバーに同時接続可能なクライアント数を調整する
【C++】staticメンバ変数がundefined referenceとエラーになる場合