iOS8のRemote Notificationの登録メソッドについて


選択肢付きのプッシュの登場によってとんでもなく面倒くさい仕様変更が起こった。

## `registerForRemoteNotificationTypes:`がiOS8から使用不可能になる

### Declaration

```
- (void)registerForRemoteNotificationTypes:(UIRemoteNotificationType)types
```

### 変更内容

APNsサーバへ登録する際に使用していた、`registerForRemoteNotificationTypes:`がiOS8から使えなくなった。
代わりに、`registerForRemoteNotifications`を使用する。

`UIRemoteNotificationType`は`UIUserNotificationType`に変更。
`UIUserNotificationSettings`で設定する。

#### UIUserNotificationSettings

以下のメソッドで設定クラスを生成する。

```
+ (instancetype)settingsForTypes:(UIUserNotificationType)allowedUserNotificationTypes
                      categories:(NSSet *)actionSettings
```

ちなみに2つ目の引数のcategoriesは新機能の選択肢付きプッシュのコンテンツを渡す。

### 実装について

#### iOS7以前

``` objectivec:iOS7以前
UIRemoteNotificationType types = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:types];
```

#### iOS8

``` objectivec:iOS8
UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;

UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];

[[UIApplication sharedApplication] registerForRemoteNotifications];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
```


### iOS7以前とiOS8の共存

iOS7以前も、iOS8もフォローしたい場合、UIDeviceのバージョン比較で処理を分岐させる

```objectivec:OSによる処理の条件分岐
NSString *currentVersion = [[UIDevice currentDevice] systemVersion];
if([currentVersion compare:@"8.0" options:NSNumericSearch] == NSOrderedAscending){
	// i0S7以前の処理
} else {
	// iOS8の処理
}
```

#### `UIRemoteNotificationType`と`UIUserNotificationType`

NotificationTypeの構造体も地味に変更されている。

##### UIRemoteNotificationType

```objectivec:UIRemoteNotificationType
typedef NS_OPTIONS(NSUInteger, UIRemoteNotificationType) {
    UIRemoteNotificationTypeNone    = 0,
    UIRemoteNotificationTypeBadge   = 1 << 0,
    UIRemoteNotificationTypeSound   = 1 << 1,
    UIRemoteNotificationTypeAlert   = 1 << 2,
    UIRemoteNotificationTypeNewsstandContentAvailability = 1 << 3,
} NS_ENUM_DEPRECATED_IOS(3_0, 8_0, "Use UIUserNotificationType for user notifications and registerForRemoteNotifications for receiving remote notifications instead.");
```

##### UIUserNotificationType

```objectivec:UIUserNotificationType
typedef NS_OPTIONS(NSUInteger, UIUserNotificationType) {
    UIUserNotificationTypeNone    = 0,      // the application may not present any UI upon a notification being received
    UIUserNotificationTypeBadge   = 1 << 0, // the application may badge its icon upon a notification being received
    UIUserNotificationTypeSound   = 1 << 1, // the application may play a sound upon a notification being received
    UIUserNotificationTypeAlert   = 1 << 2, // the application may display an alert upon a notification being received
} NS_ENUM_AVAILABLE_IOS(8_0);
```

Newsstandのタイプがなくなっている。

##### 暫定的対応策

iOS7以前とiOS8を共存する場合の暫定的対応（Newsstandのことは無視してる）

```objectivec:UIRemoteNotificationTypeをUIUserNotificationTypeに変換する
UIRemoteNotificationType remoteTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert;

UIUserNotificationType userTypes = (UIUserNotificationType)remoteTypes;
```


## その他さようならしたメソッド

### `enabledRemoteNotificationTypes`

現在設定されている`UIRemoteNotificationType`を取得するメソッド。
`isRegisteredForRemoteNotifications`を代わりに使用するようになった。


## 参考ページ

- [Whats's New in iOS Notifications (PDF)](http://devstreaming.apple.com/videos/wwdc/2014/713xx1il4h4ur9c/713/713_whats_new_in_ios_notifications.pdf)  
→ これを読めばだいたいわかる。
- [iOS Developer Library - Pre-Release](https://developer.apple.com/library/prerelease/ios/navigation/)  
→ iOS8のリファレンス。ここでDeprecatedされたクラスなどを確認できる。
 - [UIApplication Class Reference](https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIApplication_Class/index.html#//apple_ref/occ/cl/UIApplication)
 - [UIUserNotificationSettings Class Reference](https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIUserNotificationSettings_class/index.html#//apple_ref/doc/c_ref/UIUserNotificationSettings)