iOS8とiOS7にプッシュ通知を送る


iOS8では、プッシュ通知から直接返信するなどのアクションが出来るようになりましたが、
それに伴って通知の仕様も大きく変更されました。

この記事では基本的な手順とパラメータの変更点について簡単にまとめています。

プッシュ通知の登録手順の変更

上で述べた通知の機能拡張に伴い、アクションのない(=iOS7以前と同様の)プッシュ通知を行う場合でも実装方法が変わりました。
具体的には、これまでプッシュ通知の登録時に使用していたregisterForRemoteNotificationTypes:メソッドが非推奨になり、
registerUserNotificationSettings:メソッドとregisterForRemoteNotificationsメソッドを使う形になりました。

メソッド名だけ並べても分かりにくいので実際のコードで示すと

iOS7以前ではこうだったのが…

  [application registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];

iOS8からはこうなりました。

  UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound;
  UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];

  [application registerUserNotificationSettings:settings];
  [application registerForRemoteNotifications];

つまり、

iOS8のプッシュ通知登録は

  1. UiUserNotificationSettingクラスのインスタンスに通知の設定を行い
  2. その設定をアプリに登録し
  3. アプリにプッシュ通知の登録を行う

という形になっています。
(今回は説明を省略しましたが、UiUserNotificationSettingクラスの設定を変えることで、プッシュ通知からさまざまなアクションを実行可能にできます。)

また、通知の種類(バッジ、アラートなど)の許可設定パラメータについても変更がなされているのですが、
パッと見では気づきにくい(というより自分が気づけなかっただけですが…)変更点なので注意が必要です。
(これについては後述します。)

もちろん、新しいメソッドはiOS7以前では使えないので、
iOS8・iOS7のそれぞれのデバイスに対してプッシュ通知を行う場合は以下のような処理になります。

// OSのバージョンを取得
CGFloat currentVersion = [[[UIDevice currentDevice] systemVersion] floatValue];

if (currentVersion >= 8.0) {

  // iOS 8 以降の処理

  // User Notificationの種類(バッヂ、アラート、サウンド)
  UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound;

  // User Notificationの設定を登録
  UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
  [application registerUserNotificationSettings:settings];

  // Remote Notificationの設定を登録
  [application registerForRemoteNotifications];

} else {

  // iOS 7 以前の処理

  // Remote Notificationの種類(バッヂ、アラート、サウンド)
  UIRemoteNotificationType types = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;

  // Remote Notificationの設定を登録
  [application registerForRemoteNotificationTypes:types];

}

通知の種類を示すパラメータの変更

バッヂやアラートなど、通知の種類の設定方法は、大きな変更はありません。
ですが、iOS7以前ではUIRemoteNotificationTypeBadgeなどを使っていましたが、
iOS8移行ではUIUserNotificationTypeBadgeなどを使って指定するように変更されました。

とはいえ、iOS8でもUIRemote~のほうも使用できますし、指し示す値も変更はないので、動きはするのですが、それゆえに変更に気づくのに時間がかかりました。

※正確には、UIUser~のパラメータにはiOS7以前にあったUIRemoteNotificationTypeNewsstandContentAvailabilityに相当するものはなくなっているようです

通知許可設定を参照するプロパティの変更

通知の種類を示すパラメータがUIRemote~からUIUser~に変わったのと同様に、
デバイス側の通知許可設定を参照するプロパティも変更になりました。

iOS7以前ではenabledRemoteNotificationTypesプロパティで参照していたものが、
iOS8からはisRegisteredForRemoteNotificationsプロパティで参照するようになりました。

なので、iOS8/iOS7のそれぞれにおいて通知許可設定を参照する場合は以下のような処理になります。

// アプリの Remote Notification 許可設定
UIRemoteNotificationType types = UIRemoteNotificationTypeNone;

// OSのバージョンによって、許可設定の取得先が異なる
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {

  // iOS 8 以降
  types = [application isRegisteredForRemoteNotifications];

} else {

  // iOS 7 以前
  types = [application enabledRemoteNotificationTypes];
}