[Amazon Pinpoint] Amazon Mobile Analytics からの移行ガイド – iOS 編

Amazon Pinpoint の機能の一部は Amazon Mobile Analytics が活用されている

Amazon Pinpoint (以降 Pinpoint) は、セグメントされたプッシュ通知をモバイルアプリに送信するためのサービスです。概要については下記の記事を参考にしてください。

Pinpoint 自体は新しいサービスですが、一部の機能は Amazon Mobile Analytics (以降 Mobile Analytics) が活用されています。

以前 Amazon Mobile Analytics の一部であった機能は、すべて Amazon Pinpoint サービスで利用できるようになりました。Pinpoint では、Mobile Analytics と同様に、アプリケーションの使用状況や収益を計測できます。さらに、Pinpoint ではこの機能が拡大されており、ターゲットを絞ったキャンペーンを簡単に実施してユーザーの利用度を高めることができます。Amazon Pinpoint は、ユーザーの行動を把握し、ターゲットにするユーザーや送信するメッセージを決定し、メッセージを配信する最適な時間を計画し、キャンペーン開始後にキャンペーンの結果を追跡するのに役立ちます。以前に Mobile Analytics を使用したことのあるお客様は、ぜひ Amazon Pinpoint をお試しください。

Amazon Mobile Analytics

Mobile Analytics と同様にアプリケーションの使用状況や収益を計測しつつ、計測したデータを元にセグメント(対象のユーザーを絞り込み)したユーザーにプッシュ通知を送ることができるサービス、それが Pinpoint です。すでに Mobile Analytics を導入済みのモバイルアプリを対象とする場合は、Pinpoint を使うべきでしょう。

本ブログでは、Mobile Analytics をすでに導入されている場合に、どのように Pinpoint に移行するか考えてみることにしました。

Mobile Analytics の App は Pinpoint の App として利用出来る

Mobile Analytics の App は、そのまま Pinpoint の App として利用することができます。例えば次のように SampleApp という名前で、Mobile Analytics の App を作ったとします。

pinpoint-analytics-01

Pinpoint を開いてみると SampleApp が表示されていることが確認できます。

pinpoint-analytics-02

URL を見ると分かりますが、App Id も同じであることが確認できます。

Mobile Analytics の URL

pinpoint-analytics-03

Pinpoint の URL

pinpoint-analytics-04

APNs の証明書を登録する

Pinpoint 経由でプッシュ通知が打てるよう、APNs の証明書 (p12 ファイル) を登録します。Pinpoint の Manage 画面の Channels タブで設定を追加することができます。

pinpoint-analytics-05

Mobile Analytics を使ったアプリを開発されている場合、Amazon SNS のモバイルプッシュも併用されている方も多いかと思います。Amazon SNS には PlatformApplication に証明書を設定すると思いますが、それに似たような作業です。

証明書の作り方は、下記のブログを参考にしてください。

SDK を導入する

次に、アプリ側の設定に移ります。まずは Pinpoint の SDK を組み込みましょう。

pod 'AWSPinpoint', '~> 2.4.15'

次に Info.plist に Pinpoint の設定を追加します。AWS SDK for iOS の環境設定は、以前はコード上に記述していましたが、現在は Info.plist に書く方法が一般的です。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>AWS</key>
	<dict>
		<key>CredentialsProvider</key>
		<dict>
			<key>CognitoIdentity</key>
			<dict>
				<key>Default</key>
				<dict>
					<key>PoolId</key>
					<string>YOUR_COGNITO_ID_POOL_GOES_HERE</string>
					<key>Region</key>
					<string>us-east-1</string>
				</dict>
			</dict>
		</dict>
		<key>PinpointAnalytics</key>
		<dict>
			<key>Default</key>
			<dict>
				<key>AppId</key>
				<string>YOUR_APP_ID_GOES_HERE</string>
				<key>Region</key>
				<string>us-east-1</string>
			</dict>
		</dict>
		<key>PinpointTargeting</key>
		<dict>
			<key>Default</key>
			<dict>
				<key>Region</key>
				<string>us-east-1</string>
			</dict>
		</dict>
	</dict>
</dict>

Cognito Identity Pool Id は、Federated Identity の機能 (SNS ログインなど) を使わないのであれば Mobile Analytics の App 作成時に自動的に生成された共有のものを使う形で問題はないです。Unauth の IAM Role の Policy は mobileanalytics:PutEventsmobiletargeting:UpdateEndpoint を許可する必要がある点にご留意ください。


 {
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "mobileanalytics:PutEvents"
      ],
      "Resource": [
        "*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "mobiletargeting:UpdateEndpoint"
      ],
      "Resource": [
        "arn:aws:mobiletargeting:*:*:apps/*"
      ]
    }
  ]
}

アプリの実装方法を変更する

デバイストークンの登録

Pinpoint では、新たにデバイストークンを Pinpoint に送信する処理が必要になります。

まず AppDelegate の application(_:didFinishLaunchingWithOptions:) メソッドで、Pinpoint のサービスをインスタンス化します。そして application:didRegisterForRemoteNotificationsWithDeviceToken: のメソッド内で Pinpoint のマネージャのメソッドを呼ぶようにします。

import UIKit
import AWSPinpoint

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var pinpoint: AWSPinpoint!
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
        
        // Pinpointを初期化する
        let pinpointConfiguration = AWSPinpointConfiguration.defaultPinpointConfiguration(launchOptions: launchOptions)
        pinpoint = AWSPinpoint(configuration: pinpointConfiguration)
        
        // Remote Notificationを登録する
        registerRemoteNotification()
        
        return true
    }
    
    func registerRemoteNotification() {
        let settings = UIUserNotificationSettings(types: [.badge, .alert, .sound], categories: nil)
        UIApplication.shared.registerUserNotificationSettings(settings)
        UIApplication.shared.registerForRemoteNotifications()
    }
    
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        print(#function)
        pinpoint.notificationManager.interceptDidRegisterForRemoteNotifications(withDeviceToken: deviceToken)
    }
    
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print(#function)
    }
    
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        print(#function)
        pinpoint.notificationManager.interceptDidReceiveRemoteNotification(userInfo, fetchCompletionHandler: completionHandler)
    }

}

Endpoint Profile の送信

Pinpoint には、Mobile Analytics にはない Endpoint という設定があります。こちらはいわばアプリ利用ユーザーの設定値を表しており、設定しておくことで、セグメントのルールに使うことができます。例えば、次のように登録します。

func registerProfile() {
    let client = pinpoint.targetingClient
    // 現在のプロフィールを取得
    let profile = client.currentEndpointProfile()
    // Endpoint Idをログ出力しておく
    print("endpointId = \(profile.endpointId)")
    // 独自のユーザーIDを設定できる
    profile.user?.userId = "1234567890"
    // 独自の属性値を設定できる
    profile.addAttribute(["Pop", "Rock"], forKey: "Favorite")
    // 更新すると変更内容が送信される
    client.update(profile)
}

endpointId をログに出しておきます。後で Profile が設定されているか確認するときに使います。

イベントの送信

Mobile Analytics では、イベントの送信を以下のような感じで実装していたと思います。弊社では、例えば以下のような共通で呼び出せるメソッドを作り、そこ経由でどこからでもイベントを発行できるようにしています。

public func notifyAnalyticsEvent(type: String, action: String, id: String) {
    // サービスのインスタンスを取得
    let analytics = AWSMobileAnalytics.default()
    // クライアントのインスタンスを取得
    let client = analytics.eventClient
    // 共通で設定する属性値を設定
    client.addGlobalAttribute(Device.uuid, forKey: "uuid")
    // イベントを作成
    if let event = client.createEvent(withEventType: type) {
        // 属性値の追加
        event.addAttribute(action, forKey: "action")
        event.addAttribute(id, forKey: "id")
        // 記録
        client.record(event)
        // 記録されているものを送信
        client.submitEvents()
    }
}

ここを、Pinpoint に置き換えてみます。ほぼ一緒であることがわかると思います。

public func notifyAnalyticsEvent(type: String, action: String, id: String) {
    // クライアントのインスタンスを取得
    let client = pinpoint.analyticsClient
    // 共通で設定する属性値を設定
    client.addGlobalAttribute("1234567890", forKey: "uuid")
    // イベントを作成
    let event = client.createEvent(withEventType: type)
    // 属性値の追加
    event.addAttribute(action, forKey: "action")
    event.addAttribute(id, forKey: "id")
    // 記録
    client.record(event)
    // 記録されているものを送信
    client.submitEvents()
}

テストする

アプリを起動したあと、イベントをフィルタリングしてみると、送信したイベントが取れていることが確認できました。

pinpoint-analytics-06

最後に Pinpoint の GetEndpoint API を、AWS CLI から呼び出してみましょう。

$ aws pinpoint get-endpoint \
--region us-east-1 \
--application-id <Pinpoin App Id> \
--endpoint-id <ログで確認した Endpoint Id> | jq .

こんな感じのデータが取得できました。FavoriteUserId が記録されていることが確認できました。

{
  "EndpointResponse": {
    "EffectiveDate": "2016-12-13T02:40:03.750Z",
    "OptOut": "NONE",
    "RequestId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "Demographic": {
      "Locale": "ja_US",
      "Make": "apple",
      "AppVersion": "1.0.0",
      "Platform": "ios",
      "PlatformVersion": "10.1.1",
      "Timezone": "Asia/Tokyo",
      "Model": "iPhone"
    },
    "User": {
      "UserId": "1234567890",
      "UserAttributes": {
        "Favorite": [
          "Pop",
          "Rock"
        ]
      }
    },
    "Metrics": {},
    "Location": {
      "Country": "US"
    },
    "Address": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "CohortId": "54",
    "Attributes": {
      "Favorite": [
        "Pop",
        "Rock"
      ]
    },
    "ChannelType": "APNS",
    "CreationDate": "2016-12-13T02:40:03.750Z",
    "ApplicationId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "Id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "EndpointStatus": "ACTIVE"
  }
}

まとめ

Mobile Analytics を導入済みの場合は、敷居がかなり低いです。導入されてみてはいかがでしょうか。

参考