FirebaseのMethod Swizzling
FirebaseのSDKを組み込んだ場合、デフォルトではMethod Swizzling
を使ってAPNsの設定等を行っているようですが、Info.plistに以下の設定をするとそれを無効にすることが出来ます。
FirebaseAppDelegateProxyEnabled = NO
無効にした場合は、SDKが行っていた部分を自前で実装する必要が出てきますが、有効にするか無効にするかは場合によって変わってくると思います。
FirebaseがMethod Swizzlingを使って何をやっているのかを把握しておきたいので調べてみました。
検証環境
- XCode 7.3.1
- iOS 8.1以上
- Swift 2.2.1
Firebase Cloud MessagingがMethod swizzlingを実行する箇所
ドキュメントを引用
The FCM API performs method swizzling in two key areas: mapping your APNs token to the FCM registration token and capturing analytics data during downstream message callback handling. Developers who prefer not to use swizzling can disable it by adding the flag FirebaseAppDelegateProxyEnabled in the app’s Info.plist file and setting it to NO (boolean value). Relevant areas of the guides provide code examples, both with and without method swizzling enabled.
ドキュメントによると、mapping your APNs token
とdownstream message callback handling.
の2箇所が該当の処理のようです。
mapping your APNs tokenについて
デバイストークンをFCMのトークンにマッピングする処理で、APNSに通信してデバイストークンを取得したあと、デバイストークンをFirebaseのサーバに送ります。
Method Swizzling
を無効にした場合は以下の処理を実装する必要があります。
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) { FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenTypeSandbox) }
downstream message callback handlingについて
FMCのトラッキングや分析に関する処理のようです。
これも同じく、Method Swizzling
を無効にした場合は以下の処理を実装する必要があります。
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) { // Let FCM know about the message for analytics etc. FIRMessaging.messaging().appDidReceiveMessage(userInfo) // handle your message }
注意点
検証した結果、Method Swizzling
が有効になっていると、iPhone5の端末(iOS9.4.3)でのみリフレッシュトークンの取得時に端末が落ちるという問題が発生しました。
これは初回起動時のみに発生し、次回の起動時からは発生しません。
実装したのは以下のとおりです。
//アプリ起動時にトークン更新のオブザーバを登録 NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.tokenRefreshNotification(_:)), name:kFIRInstanceIDTokenRefreshNotification, object: nil)
オブザーバで指定しているメソッド
(検証用コードなのでトークンをprintしているだけです)
func tokenRefreshNotification(notification: NSNotification) { let token = FIRInstanceID.instanceID().token()! print("InstanceID token: \(token)") }
実装方法が悪いのか何なのか原因がわかりませんが、解決出来ない場合はMethod Swizzlingを無効にして自前で実装したほうが良さそうです。
TAG
新しいことや難しい課題に挑戦することにやりがいを感じ、安定やぬるい事は退屈だと感じます。 考えるより先に手が動く、肉体派エンジニアで座右の銘は諸行無常。 大事なのは感性、プログラミングにおいても感覚で理解し、感覚で書きます。
TAG
- Android
- AWS
- Bitrise
- CodePipeline
- Firebase
- HTML
- iOS
- IoT
- JavaScript
- KPI
- Linux
- Mac
- Memcached
- MGRe
- MGReのゆるガチエンジニアブログ
- MySQL
- PHP
- PICK UP
- PR
- Python
- Ruby
- Ruby on Rails
- SEO
- Swift
- TIPS
- UI/UX
- VirtualBox
- Wantedly
- Windows
- アクセス解析
- イベントレポート
- エンジニアブログ
- ガジェット
- カスタマーサクセス
- サーバ技術
- サービス
- セキュリティ
- セミナー・展示会
- テクノロジー
- デザイン
- プレスリリース
- マーケティング施策
- マネジメント
- ラボ
- リーンスタートアップ
- 企画
- 会社紹介
- 会社紹介資料
- 勉強会
- 実績紹介
- 拡張性
- 採用
- 日常
- 書籍紹介
- 歓迎会
- 社内イベント
- 社員インタビュー
- 社長ブログ
- 視察
- 開発環境