yamaday0u Blog Written by yamaday0u

【誰よりも丁寧に解説!】SwiftUI × Firebaseでプッシュ通知を受け取るiOSアプリを実装

iOS

こんにちは、やまだゆうです。
今回はSwiftUIとFirebaseの組み合わせでプッシュ通知を受け取るアプリを実装する方法をお伝えします!

この記事はこんな悩みを解決します

  • SwiftUIとFCMでプッシュ通知機能を作りたい
  • 実装方法を調べても出てくる情報が断片的でわかりにくい

この記事ではSwiftUIでFCMを使ったプッシュ通知を実装する方法をたくさんのスクリーンショットやコードサンプルとともに徹底的に説明します!

この記事の内容

  1. 前提・全体像
  2. Apple Developer ProgramでAPNs認証キーを作る
  3. Firebaseプロジェクトをアプリに組み込む
  4. APNsとFirebaseを連携させる
  5. いざ、テスト

スポンサーリンク

前提・全体像

前提

本記事は以下の準備が完了していることが前提です。

  • Apple Developer Programの登録
  • Firebaseの登録 ※Googleアカウントを持っていればすぐに利用できます。

参考情報

基本的には公式サイトの説明を順序立ててわかりやすくしています。

Apple プラットフォームで Firebase Cloud Messaging クライアント アプリを設定する

Apple Developer ProgramでAPNs認証キーを作る

まずはプッシュ通知に必要なAPNs認証キーを作りましょう。

Apple Developer ProgramのMembershipページで 【証明書、ID、プロファイル】 > 【キー】をクリックします。
Keysの横にある【+】ボタンをクリックします。
【Key Name】と【Apple Push Notifications service(APNs)】に入力して【Continue】をクリックします。
【Register】をクリック
ここは少しやることが多いです。以下の操作をしてください。
  1. 【Key ID】の内容をコピー
    ※FirebaseにAPNs認証キーを登録するときに使います。
  2. 【Download】ボタンをクリックして認証キー(p8ファイル)をダウンロード
    ※FirebaseにAPNs認証キーを登録するときに使います。
  3. 【Done】をクリック

スポンサーリンク

Firebaseプロジェクトをアプリに組み込む

この項目でやること

  1. Firebaseプロジェクトの作成&iOSアプリの登録
  2. Firebase SDKをインポート
  3. 初期化コードを追加

Firebaseプロジェクトの作成&iOSアプリの登録

Firebase コンソール にアクセスします。

【プロジェクトを作成】をクリック
【プロジェクト名】を入力して【続行】をクリック
【このプロジェクトでGoogleアナリティクスを有効にする】にチェックを外して【続行】をクリック
ここは好みによりけりなので有効にしてもいいです。今回はプッシュ通知に集中したいので無効化しています。
作成されたプロジェクト画面で【iOS】のアイコンをクリック
Apple バンドル ID にアプリのバンドルIDを入力する

次に設定ファイルをダウンロードします。

ダウンロードした GoogleService-Info.plist ファイルを Xcode プロジェクトのルートディレクトリに配置し、 すべてのターゲットに追加します。

プロジェクトのルートディレクトリにGoogleService.plistファイルを配置
Xcodeでプロジェクトを開き、メインのディレクトリでメニューを表示し【Add Files to “ディレクトリ名”…】を選択して、ルートディレクトリに配置したGoogleService.plistファイルを指定します。
こんな感じで配置されればOK

Firebase SDKをインポート

Firebase SDKをアプリにインポートする方法はいくつかあります。ここではCocoaPodsを使ってインポートします。
※CocoaPodsが未インストールの方は、上記リンク先にインストール方法へのリンクが載っているので参考にしてみてください。

プロジェクトのルートディレクトリでPodfileを作成します。

pod init

アプリで使いたいFirebase Podを追加します。

target 'PushNotificationSample' do
  use_frameworks!

  # FCM の Firebase Pod を Podfileに追加
  pod 'FirebaseMessaging'

  target 'PushNotificationSampleTests' do
    inherit! :search_paths
  end

  target 'PushNotificationSampleUITests' do

  end

end

Podをインストールします。

pod install --repo-update

.xcworkspaceファイルが作成されるのでXcodeで開きましょう。これからはここでコーディングを行います。

.xcworkspaceファイルをXcodeで開く

初期化コードを追加

AppDelegate.swiftファイルを作成して、以下のDelegateを追加します。

import SwiftUI
import FirebaseCore


class AppDelegate: NSObject, UIApplicationDelegate {
  func application(_ application: UIApplication,
                   didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    FirebaseApp.configure()
    return true
  }
}

アプリの起動時に Firebase を接続するために、アプリのメインエントリポイント(今回の場合はPushNotificationSample.swift)に次の初期化コードを追加します。

@main
struct YourApp: App {
  // register app delegate for Firebase setup
  @UIApplicationDelegateAdaptor(AppDelegate.self) var delegate

  var body: some Scene {
    WindowGroup {
      NavigationView {
        ContentView()
      }
    }
  }
}

APNsとFirebaseを連携させる

この項目でやること

  1. APNs認証キーをFirebaseプロジェクトにアップロードする
  2. リモート通知に登録する
  3. Messagingのデリゲートを追加する
  4. APNsトークンをFCMトークンにマッピングする

APNs認証キーをFirebaseプロジェクトにアップロードする

FirebaseとAPNsが連携できるように、APNs認証キーをFirebaseプロジェクトにアップロードします。

【プロジェクトの設定】 > 【Cloud Messaging】> 対象のApple アプリ
3項目すべてが必須になります。

キーIDとチームIDはそれぞれApple Developer Programの以下の部分で確認ができます。

キーID:Apple Developer ProgramのMembershipページで 【証明書、ID、プロファイル】 > 【キー】 > 作成したキーの詳細ページ
チームID:Apple Developer ProgramのMembershipページ > 【メンバーシップの詳細】欄

リモート通知に登録する

アプリを起動したときにリモート通知に登録できるようにAppDelegate.swiftに以下のコードを追加します。

import SwiftUI
import FirebaseCore


class AppDelegate: NSObject, UIApplicationDelegate {
  func application(_ application: UIApplication,
                   didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    FirebaseApp.configure()

    // 追加(ここから)
    UNUserNotificationCenter.current().delegate = self

    let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
    UNUserNotificationCenter.current().requestAuthorization(
      options: authOptions,
      completionHandler: { _, _ in }
    )

    application.registerForRemoteNotifications()
    // 追加(ここまで)

    return true
  }
}

Messagingのデリゲートを追加する

トークンを受信するためにMessagingのデリゲートをAppDelegate.swiftに設定します。

import SwiftUI
import FirebaseCore


class AppDelegate: NSObject, UIApplicationDelegate {
  func application(_ application: UIApplication,
                   didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    FirebaseApp.configure()

    UNUserNotificationCenter.current().delegate = self

    let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
    UNUserNotificationCenter.current().requestAuthorization(
      options: authOptions,
      completionHandler: { _, _ in }
    )

    application.registerForRemoteNotifications()

    // デリゲートを追加
    Messaging.messaging().delegate = self

    return true
  }
}

APNsトークンをFCMトークンにマッピングする

SwiftUIで作るiOSアプリでFCMを使えるようにするためには、APNsトークンをFCMトークンにマッピングする必要があります。

引数が異なるもう1つのapplication()メソッドを実装します。

import SwiftUI
import FirebaseCore


class AppDelegate: NSObject, UIApplicationDelegate {
  func application(_ application: UIApplication,
                   didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    // 中略
  }

  // 追加
  func application(_ application: UIApplication,
                     didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        // APNsトークンをFCMトークンにマッピング
        Messaging.messaging().apnsToken = deviceToken
}

合わせて、FirebaseAppDelegateProxyEnabledNOを設定します。これがないとプッシュ通知を受け取れません。
※公式ページにもしれっと書いてあって、見つけ出すのに苦労した思い出があります。

スポンサーリンク

いざ、テスト

トークンを表示するコードを追加

生成したトークンを受け取り、表示するためのコードを追加します。

import SwiftUI
import FirebaseCore


class AppDelegate: NSObject, UIApplicationDelegate {
  func application(_ application: UIApplication,
                   didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    // 中略
  }

  func application(_ application: UIApplication,
                     didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    // 中略
  }
}

extension AppDelegate: UNUserNotificationCenterDelegate, MessagingDelegate { /* MessagingDelegateはFIRMessagingDelegateの別名 */
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        Messaging.messaging().token { token, error in
            if let error = error {
                print("Error fetching FCM registration token: \(error)")
            } else if let token = token {
                print("FCM registration token: \(token)")
            }
        }
    }
}

アプリをビルドする

アプリをビルドして、生成したトークンがXcodeのログに表示されればOKです!

実運用では、取得したトークンをサーバーに渡す処理をさらに追加してプッシュ通知を送れるようにします。

以上、長い道のりでしたがここまで付いてきてくれてありがとうございます。お疲れ様でした!

yamaday0uを応援お願いします!あなたの1クリックが励みになります。
>> にほんブログ村