iOS 10 時代の Notification

※本記事は、[一般に公開されている情報](https://developer.apple.com/reference/usernotifications)を元に作成しています
※図は WWDC 2016 の [Introduction to Notifications](https://developer.apple.com/videos/play/wwdc2016/707/)より引用しています

----

WWDC 2016 で User Notifications Framework が発表されましたね。


これまでは、Remote Notification と Local Notification が別々に存在していましたが、User Notifications Framework の登場により、これらを同じフレームワークでハンドリングできるようになります。

![IMG_2107.PNG](https://qiita-image-store.s3.amazonaws.com/0/8292/fff52a41-13d6-5414-13c2-ffad06616fbb.png)

この中で個人的に注目なのは、**In-app presentation option（アプリを起動中にも画面上に通知を表示できる）**という点。詳しくは後述します。

![IMG_2112.PNG](https://qiita-image-store.s3.amazonaws.com/0/8292/2d1bef89-f353-82e9-e3c9-126f502cc49a.png)


通知が発生するトリガーとして次の4つが用意されています。

* Push
* Time Interval
* Calendar
* Location

1つ目の「Push」が従来の Remote Notification にあたり、残り3つは Local Notification にあたるものと思われます。ちなみに、UILocalNotification は iOS 10 で **deprecated** になっています。

# 使い方

さっそく使ってみましょう。

## Push

まずは `UserNotifications` をインポートします。

```swift
import UserNotifications
```

ユーザーに通知の許可を要求します。

```swift
UNUserNotificationCenter.current().requestAuthorization([.alert, .sound, .badge]) {
    (granted, error) in
    // ...
}
```

UserNotifications の Prefix は `UN` のようですね :grinning: 

ちなみに、iOS 8 で登場した `UIUserNotificationSettings` もまた iOS 10 で **deprecated** になっています。短い命でしたね :cry: 

次に Token を登録します。メソッドは今までどおり

```swift
UIApplication.shared().registerForRemoteNotifications()
```

を使用します。

これで登録は完了です。デバイストークンを登録したサーバなどから通知を送ってみましょう。

![IMG_2111.PNG](https://qiita-image-store.s3.amazonaws.com/0/8292/04e0896a-68ab-dfbb-3608-e3b35e85f69a.png)

成功するとこのような通知が表示されます。通知にはタイトル、サブタイトル、本文がセットできるようです。

![image](https://qiita-image-store.s3.amazonaws.com/0/8292/4777f49d-61c4-c37b-4426-cb0c4a3ef54e.png)

これに加え、画像もセットできるようですがこの記事では触れません。詳細は [Advanced Notifications - WWDC 2016 - Videos - Apple Developer](https://developer.apple.com/videos/play/wwdc2016/708/) をご覧ください。



## Time Interval

以下は5秒後に通知を１回だけ表示するサンプルコードです。

```swift
let content = UNMutableNotificationContent()
content.title = "Introduction to Notifications"
content.body = "Let's talk about notifications!"

let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)

let requestIdentifier = "sampleRequest"
let request = UNNotificationRequest(identifier: requestIdentifier,
                                    content: content,
                                    trigger: trigger)

UNUserNotificationCenter.current().add(request) {
    (error) in
    // ...
    print(error)
}
```

`identifier` は後で通知を消したり更新したりする際に使うようです（詳しくはビデオを参照）。

通知が表示されるタイミングでデリゲートを受け取ることもできます。

```swift
class ViewController: UIViewController, UNUserNotificationCenterDelegate {
```

```swift
UNUserNotificationCenter.current().delegate = self
```

通知が表示されると次のデリゲートメソッドが呼ばれます。

```swift
func userNotificationCenter(_ center: UNUserNotificationCenter,
                            willPresent notification: UNNotification,
                            withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
    completionHandler([.alert, .sound])
}
```

この中で `completionHandler` ハンドラーにオプションを設定すると、**アプリが起動していても通知を出すことができます。**（NDA期間中につき、実際に表示したスクリーンショットは自粛）

この通知をタップすると次のデリゲートメソッドが呼ばれます。

```swift
func userNotificationCenter(_ center: UNUserNotificationCenter,
                            didReceive response: UNNotificationResponse,
                            withCompletionHandler completionHandler: () -> Void) {
    completionHandler()
}
```



# さらに進化したNotification

iOS 10では、通知の中にカレンダーや地図を表示できるようになっています。

![IMG_2117.PNG](https://qiita-image-store.s3.amazonaws.com/0/8292/4c908fcd-87a9-989c-fcb5-d8a4e0c83918.png)

詳しく知りたい方は [Advanced Notifications - WWDC 2016 - Videos - Apple Developer](https://developer.apple.com/videos/play/wwdc2016/708/) を見ることをお勧めします。

# リンク

* [UserNotifications](https://developer.apple.com/reference/usernotifications) - Apple 公式ドキュメント
* [Introduction to Notifications - WWDC 2016 - Videos - Apple Developer](https://developer.apple.com/videos/play/wwdc2016/707/)　
* [Advanced Notifications - WWDC 2016 - Videos - Apple Developer](https://developer.apple.com/videos/play/wwdc2016/708/)