プッシュ通知の設定: iOS

プッシュ通知機能のソースコードの追加

Capabilities に Push Notifications を追加

Xcode 上で本 SDK を導入したいアプリのプロジェクトを開き、 Capabilities タブに ある Push Notifications のスイッチをONにします。

Add the “Push Notifications” entitlements to your AppID というメッセージが表示された場合

Add the “Push Notifications” entitlements to your AppID というメッセージが表示されたら、その下にある Fix Issue ボタンをクリックします。

コードを追加

プッシュ通知を利用するために AppDelegate内に以下のコードを追加します。
application:didFinishLaunchingWithOptions:内に次のコードを追加します。下記のコードが初めて処理された時に、 iOS標準 のプッシュ通知の許諾ダイアログが表示されます。

LogBase.requestDeviceToken()

application:didRegisterForRemoteNotificationsWithDeviceToken:を次のように実装します。

  func application(_ application: UIApplication,
      didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    #if DEBUG
        let env = LPDevelopment
    #else
        let env = LPProduction
    #endif
    LogBase.application(application,
      didRegisterForRemoteNotificationsWithDeviceToken: deviceToken, with: env)
  }

application:didFailToRegisterForRemoteNotificationsWithError:を次のように実装します。

  func application(_ application: UIApplication,
      didFailToRegisterForRemoteNotificationsWithError error: Error) {
    LogBase.application(application, didFailToRegisterForRemoteNotificationsWithError: error)
  }

application:didReceiveRemoteNotification:fetchCompletionHandler:を次のように実装します。

  func application(_ application: UIApplication,
    didReceiveRemoteNotification userInfo: [AnyHashable : Any],
    fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    LogBase.application(application, didReceiveRemoteNotification: userInfo,
        fetchCompletionHandler: completionHandler)
  }

UNUserNotificationCenterDelegate を利用したい場合 (iOS 10以降)

LogBase SDK の中でUNUserNotificationCenterdelegateが自動的に設定されます。このため、直接 UNUserNotificationCenterdelegateを上書きした場合は、LogBase のプッシュ通知の開封時処理は正常に動作しません。

UNUserNotificationCenterDelegateを利用したい場合には、 直接UNUserNotificationCenterdelegateを書き換えず、 LPUserNotificationCenterDelegatedelegateUNUserNotificationCenterDelegateを設定してください。

LPUserNotificationCenterDelegate.sharedInstance()!.delegate = self;

プッシュ通知の開封を処理したい場

LogBase SDK では、カスタムフィールドを用いてプッシュ通知に任意の情報を追加することができます。

  • setOpenHandler:で通知開封時の処理を登録できます。
  • setOpenHandler:initApplicationId:secretKey:launchOptions:以降に呼び出す必要があります。
LogBase.setOpenHandler({userInfo in
  // ここに通知開封時の処理
  // userInfo にはカスタムフィールドと、LogBase や APNs が通知に使う情報が含まれる。
  print("A notification is opened. userInfo: \(userInfo)")
})

デバイストークンを処理したい場合

LogBase SDK では、イベントハンドラを利用してデバイストークンを取得することができます。イベントハンドラの詳細については イベントハンドラ をご覧ください。

プッシュ通知証明書の設定

プッシュ通知機能を利用するためにはApple社から発行されたプッシュ通知の証明書が必要です。 下記の手順にしたがって、証明書を LogBase に設定して下さい。

1. 証明書の要求ファイル (CSRファイル)を作成

証明書への署名を要求するためのファイルを作成します。このファイルは後ほど証明書を取得する際に必要になります。 PC上で アプリケーション > ユーティリティ > キーチェーンアクセス を開きます。

メニューから キーチェーンアクセス > 証明書アシスタント > 認証局に証明書を要求 を選択します。

証明書アシスタントが開きますので、情報を入力します。 「ユーザのメールアドレス」及び「通称」欄には Apple Developer Program に登録したメールアドレス及び通称を入力します。 「CA のメールアドレス」欄は空欄のままにします。「要求の処理」は「ディスクに保存」を選択し、 「鍵ペア情報を指定」にチェックを入れます。

鍵ペア情報が表示されますので、そのまま続けるをクリックします。

これで証明書を取得するための準備が整いました。

2. 証明書の作成

次に証明書を作成します。ここでは先ほど作成したCSRファイルが必要になります。 まず Apple Developer の Account にアクセスし、ログインした後 Certificates, IDs & Profiles をクリックします。

Certificates > All をクリックします。

右上の「+」ボタンから新しい証明書の作成を行います。

Production の Apple Push Notification service SSL(Sandbox & Production) を選択します。

今回 LogBase を利用するアプリの App ID を選択します。
※もしApp IDがない場合は先に SDK の導入を行ってください。導入の手順内で自動的に App ID が生成されます。

CSRファイルの作成方法が表示されますが、今回は既に作成済みなのでそのまま続行します。

CSRファイルをアップロードするよう指示があるので、先ほど作成したCSRファイルをアップロードします。

証明書が作成されました。証明書をダウンロードします。

3. 証明書の書き出し

取得した証明書を LogBase で利用するために書き出します。 ダウンロードした証明書をキーチェーンアクセスで開きます。

証明書が選択された状態で、メニューから ファイル > 書き出す… を選択します。

フォーマットが個人情報交換 (.p12)になっていることを確認し、保存します。

パスワードの設定を行います。

証明書が書き出されました。

4. 証明書のアップロード

管理画面の「設定」→「プッシュ通知証明書」の iOS 用プッシュ通知証明書 の欄から証明書をアップロードしてください。

パスワードは「3. 証明書の書き出し」で設定したパスワードになります。

画像付きプッシュ機能の追加 (iOS10以降)

LogBaseExtension の作成

File > New > Target から iOS > Notification Service Extension を選択します。

Product Name にLogBaseExtensionと入力します。

Scheme をアクティベートするか確認するダイアログが表示されたら、Activate を選択します。

TARGETS からLogBaseExtensionを選択し、Pods/Pods/LogBase/Frameworks/LogBaseAppEx.frameworkを Linked Frameworks and Libraries にドラッグアンドドロップします。

CocoaPodsを使用しない場合

TARGETS から LogBaseExtension を選択したまま、General > Deployment Info で Deployment Target を 10.0に設定します。

LogBaseExtension/NotificationService にコードを追加

LogBaseExtension/NotificationServiceの先頭にLogBaseAppExを追加します。

import LogBaseAppEx

didReceive:withContentHandler:の実装を次のように変更します。
contentHandlerはLBAENotificationHandlerが呼び出すため、明示的に呼び出す必要はありません。

override func didReceive(_ request: UNNotificationRequest, withContentHandler
    contentHandler: @escaping (UNNotificationContent) -> Void) {
  self.contentHandler = contentHandler
  bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
  LBAENotificationHandler.handle(bestAttemptContent, withContentHandler: contentHandler)
}

LogBaseExtension/NotificationService全体は以下のようになります。

import UserNotifications
import LogBaseAppEx

class NotificationService: UNNotificationServiceExtension {

  var contentHandler: ((UNNotificationContent) -> Void)?
  var bestAttemptContent: UNMutableNotificationContent?

  override func didReceive(_ request: UNNotificationRequest, withContentHandler
      contentHandler: @escaping (UNNotificationContent) -> Void) {
    self.contentHandler = contentHandler
    bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

    LBAENotificationHandler.handle(bestAttemptContent, withContentHandler: contentHandler)

    // if let bestAttemptContent = bestAttemptContent {
    //     // Modify the notification content here...
    //     bestAttemptContent.title = "\(bestAttemptContent.title) [modified]"
    //
    //     contentHandler(bestAttemptContent)
    // }
  }

  override func serviceExtensionTimeWillExpire() {
    // Called just before the extension will be terminated by the system.
    // Use this as an opportunity to deliver your "best attempt" at modified content,
    // otherwise the original push payload will be used.
    if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
      contentHandler(bestAttemptContent)
    }
  }

}