AWS（SNS, Cognito）を用いてiOSアプリにプッシュ通知するまでの手順（サーバー編）

過去に自前のサーバーを用いてiOSアプリにプッシュ通知の機能を構築したことはあるものの、サーバー部分をAWS（Amazon Web Services）に置き換えたい、という状況になったため、その手順をメモとして残しておきます。（2016年5月現在）

（ Androidアプリでの手順については [こちら](http://qiita.com/MJeeeey/items/2b62b6958d8023dec1da) です。）

# 全体の流れ

前提条件としまして、iOSアプリの公開の手順は既知であるものとします。

また、AWSのリージョンは「東京」を指定しているものとします。

大まかには、以下の流れで説明していきます。

1. プッシュ通知用のCertificateの作成
1. AWS上の設定（SNS, Cognito）
1. AWS SDKの実装（Xcode）
1. プッシュ通知の送信（AWS）

# プッシュ通知用のCertificateの作成（Apple Developer）

App IDの作成までは完了していることとします。

## 証明書の発行

Apple Developer の [Add iOS Certificate](https://developer.apple.com/account/ios/certificate/create) にて、必要な証明書を発行します。

Development（開発デバッグ用）
Apple Push Notification service SSL (Sandbox)

Production（本番用）
Apple Push Notification service SSL (Sandbox & Production)

それぞれ、証明書ファイル（.cer）が作成されます。

## 証明書ファイル（.p12）の作成

上で作成した証明書ファイル（.cer）をダブルクリックで実行すると、キーチェーンアクセスに項目が追加されます。

Apple Development iOS Push Services: xxxxxxxx（開発デバッグ用）
Apple iOS Push Services: xxxxxxxx（本番用）

リストからこれらを右クリックして、「"xxxxxxxx"を書き出す...」を選択すると証明書ファイル（.p12）が得られます。


# SNS（Simple Notification Service）の設定（AWS）

ここからAWSに入ります。お持ちのAWSアカウントにログインして、サービス`SNS`を選択します。
プッシュ通知の送信部分の構築を行います。

## 1. Platform Applicationの作成

`Create Platform Application` を選択すると、入力フォーマットが表示されます。

1. `Application Name` にSNS上の識別子を記述する
1. `Push Notification Platform` で `Apple Development`（開発デバッグ用） または `Apple Production`（本番用） を選択する
1. `Choose P12 File` に証明書ファイル（.p12）をセットする
1. `Create Platform Application` ボタンを押す

これによって、以下のような Application ARN が得られます。

~~~
（開発デバッグ用）
arn:aws:sns:ap-northeast-1:xxxxxxxxxxxx:app/APNS_SANDBOX/[Application Name]
（本番用）
arn:aws:sns:ap-northeast-1:xxxxxxxxxxxx:app/APNS/[Application Name]
~~~

**`Application ARN` は AWS SDKの実装内で使用します。**

## 2. Topic の作成

Topic を作成すると、登録された複数のAndroid端末に対して一斉にプッシュ通知を送信することができます。

1. `Create Topic` を選択する
1. `Topic name` に Topic 上の識別子を記述する
1. `Create topic` ボタンを押す

これによって、以下のような Topic ARN が得られます。

~~~
arn:aws:sns:ap-northeast-1:xxxxxxxxxxxx:[Topic name]
~~~

**`Topic ARN` は AWS SDKの実装内で使用します。**


# Cognitoの設定（AWS）

サービス`Cognito`を選択します。

Cognito はユーザー識別、認証を行うサービスです。前のSNSと組み合わせることによって、モバイルへのプッシュ通知の構築を簡易に行うことができます。

## 1. Identity Poolの作成

`Getting started wizard`が開いたら、以下の手順を行います。

1. `Identity pool name` を入力する。
1. `Enable access to unauthenticated identities` をチェックする。
1. `Create Pool` ボタンを押す。

## 2. IAMロールの作成

上の設定に続き、IAMロールの作成を行います。
いったん、そのまま`許可`ボタンを押すとCognitoの設定は完了します。その後、サービス`IAM`を選択すれば編集することが可能です。

サービス`IAM`で編集する場合の手順です。

1. フレームから`ロール`を選択
2. リストから対象のロールを選択
3. `ポリシーの編集`を選択

`ポリシーの編集`は以下のように行います。

~~~json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "mobileanalytics:PutEvents",
                "cognito-sync:*"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "sns:CreatePlatformEndpoint",
                "sns:SetEndpointAttributes",
                "sns:Subscribe"
            ],
            "Resource": [
                "arn:aws:sns:ap-northeast-1:xxxxxxxxxxxx:*"
            ]
        }
    ]
}
~~~

## 3. Identity Pool Id の取得

`Identity pool` 画面右上の `Edit identity pool` をクリックすると遷移する画面にて確認できます。

~~~
ap-northeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
~~~

**`Identity Pool Id` は AWS SDKの実装内で使用します。**

# AWS SDKの実装（Xcode）

こちらはこれだけで長くなりましたので、[こちらの記事](http://qiita.com/MJeeeey/items/e6c927118748fc61a5bc) にまとめました。

参考にしたサンプルコードを紹介しておきます。
[https://github.com/awslabs/aws-sdk-ios-samples/tree/master/SNS-MobileAnalytics-Sample](https://github.com/awslabs/aws-sdk-ios-samples/tree/master/SNS-MobileAnalytics-Sample)

# プッシュ通知の送信（AWS）

サービス`SNS`を選択します。

Topic に登録された Subscription の対象にある複数台の端末に対してプッシュ通知を送信します。

1. フレームから `Topics` を選択する
1. 対象の Topic にチェックを入れて、`Publish to topic` ボタンを押す（`Publish a message` 画面に遷移します）
1. `JSON message genarator` ボタンを押す（JSON生成ダイアログが表示されます）


`Message` に「プッシュ通知テスト」と入力しておきます。
`Target Platforms` は `iOS Dev`（開発デバッグ用）と `iOS Prod`（本番用）を選択します。（状況に応じて変更してください）

`Generate JSON` ボタンを押すと、前の画面に戻り、以下のように表示されていると思います。

~~~json
{
"default": "プッシュ通知テスト", 
"APNS": "{\"aps\":{\"alert\": \"プッシュ通知テスト\"} }", 
"APNS_SANDBOX":"{\"aps\":{\"alert\":\"プッシュ通知テスト\"}}"
}
~~~

デフォルト設定ではテキストの送信のみに対応している状態のため、以下のように追記することでサウンドとアイコンへのバッジ表示にも対応します。（例では、デフォルトサウンドの追加とバッジ「1」の追加）

~~~json
{
"default": "プッシュ通知テスト", 
"APNS": "{\"aps\":{\"alert\": \"プッシュ通知テスト\",\"sound\":\"default\",\"badge\":1} }", 
"APNS_SANDBOX":"{\"aps\":{\"alert\":\"プッシュ通知テスト\",\"sound\":\"default\",\"badge\":1}}"
}
~~~

`Publish message` ボタンを押すとプッシュ通知が送信されます。登録した端末にプッシュ通知が届けば成功です。

# 最後に

AWS の仕様は随時変更になることが多いです。いろいろなWebの記事を参考にしましたが、手順や名称が変更してしまっているものがほとんどで、、それをきっかけに今回はまとめてみました。
内容の変更に気づいたときは修正していく予定です。