ちゃんと押さえておこう iOS の Push通知を利用する時の注意点

こんにちは！ iOSのPush通知、使ってますかー！
AWSのSNSとかGrowthPushとかプッシュ通知関連のBaaSも色々増えてきて、だいぶiOSのPush通知も敷居が下がり使いやすくなってきた今日この頃。

そこで今日はPush通知を利用する際に注意しておくべきポイントをまとめておこうと思います。

## デバイストークンが更新されるタイミング

デバイストークンははたして何時更新されるのか！？　その辺りの情報はAppleのドキュメントには記載されていないようで、iOS7にアップデートされた際の情報としては下記の情報がとても参考になりました。

http://blog.katty.in/4162

では、iOS7 から iOS8 へアップデートした際にはどうなるのでしょう？　実機を使って調べてみたところ**更新されませんでした！**
デバイストークンが更新されるタイミングをまとめると下記になります。

|イベント|更新されたか|
|:----|:---:|
|OSアップデート iOS6 -> 7|○|
|OSアップデート iOS7 -> 8|×|
|端末リセット|○|
|アプリの再インストール|×|
|アプリのアップデート|×|

**※** 2014/10/21 現在までに確認できた情報です。
**※** デバイストークンの更新タイミングは変更になる可能性があります。

## シミュレータではPush通知が動作しません
初めてPush通知の開発をする際に誰しもつまづくシミュレータ。
そうなんです。シミュレータではPush通知は動作しません。APNsサーバへの認証時にエラーが返ります。

## iOS8 ではデバイストークン取得時の実装が変更になりました

iOS8 からAPNsサーバへの認証APIが変更になっています。iOS7にも対応させる場合は下記のような分岐が必要になります。

```objc:Objective-C

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    BOOL iOS8 = NO;

// SDKのバージョンの判定 iOS 8 SDKだったら
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
    // iOS 8以降だったら
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
        iOS8 = YES;

        // Remote Notificationを受信するためにAPNSへデバイスを登録(iOS8から)
        UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound |
                                                                                                         UIUserNotificationTypeAlert |
                                                                                                         UIUserNotificationTypeBadge)
                                                                                             categories:nil];

        [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
#endif

    // iOS8ではなかったら
    if (!iOS8) {
        // Remote Notificationを受信するためにAPNSへデバイスを登録(iOS7まで)
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge
                                                                               | UIRemoteNotificationTypeSound
                                                                               | UIRemoteNotificationTypeAlert)];
    }

    return YES;
}
```

## （おまけ）AWSのSNSを使っていて通知が届かない場合は送信先ステータスに注意

releaseビルド、debugビルドのプロビショニングプロファイルを間違えて指定してしまった場合など、Push通知のSSL証明書が入れ替わってしまい、Push通知が届かない場合があります。

その場合、送信先のステータスが false に更新されてしまい、それ以降は正しい証明書を指定しても通知が届かなくなってしまいます。

**例）AWS SDK for PHP でのエラースタックトレース**

```
ERROR - 2014-10-16 14:37:18 --> Endpoint is disabled
ERROR - 2014-10-16 14:37:18 --> #0 phar:../aws.phar/Aws/Common/Exception/NamespaceExceptionFactory.php(76): Aws\Common\Exception\NamespaceExceptionFactory->createException('Aws\\Sns\\Excepti...', Object(Guzzle\Http\Message\EntityEnclosingRequest), Object(Guzzle\Http\Message\Response), Array)
#1 phar:../aws.phar/Aws/Common/Exception/ExceptionListener.php(55): Aws\Common\Exception\NamespaceExceptionFactory->fromResponse(Object(Guzzle\Http\Message\EntityEnclosingRequest), Object(Guzzle\Http\Message\Response))
#2 [internal function]: Aws\Common\Exception\ExceptionListener->onRequestError(Object(Guzzle\Common\Event), 'request.error', Object(Symfony\Component\EventDispatcher\EventDispatcher))
#3 phar:../aws.phar/Symfony/Component/EventDispatcher/EventDispatcher.php(164): call_user_func(Array, Object(Guzzle\Common\Event), 'request.error', Object(Symfony\Component\EventDispatcher\EventDispatcher))
#4 phar:../aws.phar/Symfony/Component/EventDispatcher/EventDispatcher.php(53): Symfony\Component\EventDispatcher\EventDispatcher->doDispatch(Array, 'request.error', Object(Guzzle\Common\Event))
#5 phar:../aws.phar/Guzzle/Http/Message/Request.php(589): Symfony\Component\EventDispatcher\EventDispatcher->dispatch('request.error', Object(Guzzle\Common\Event))
...
```

その場合はAWSのコンソールまたはAPIにて該当のエンドポイントを再度有効にしてあげる必要があります。

###おしまい

アプリユーザの問合せを減らしユーザ満足度を最大化する、アプリ内FAQとメッセーンジャーツール「アプリヘルプ」では以上の問題を乗り越え、問合せへの返信をPush通知で返すことができます。

ご興味のある方は[製品サイト](http://www.applihelp.com/?qi2)を是非ご覧ください！