iOS10でUNNotificationAttachmentを使ってみた


[前回](http://qiita.com/s-kaneko617/items/d65eb3f34807269b7e68)新たに追加されたUNUserNotificationCenterを利用したローカルPushを試してみましたが、そこから発展させて画像付きのPushを使ってみます。

## Notificationに画像等を追加してみる

UNNotificationAttachmentを利用するとNotification表示時にメディアコンテンツを追加することができるようになります。
サポート対象のファイルは[こちら](https://developer.apple.com/reference/usernotifications/unnotificationattachment)で確認してください。
画像をNotificationに表示させてみます。
※サンプルはプロジェクト内のimage.jpgという名前の画像ファイルを表示しています。

```swift
		 // まずはNotificationに表示させるコンテンツデータを作成します。
        let content = UNMutableNotificationContent()
        content.title = "サンプルのローカルPushです"
        content.subtitle = "サンプルのsubtitleです"
        content.body = "サンプルのbodyです"
        content.badge = 1
        content.sound = .default()
        
        // 画像表示用のAttachmentを作成します。
        if let imageUrl = Bundle.main.url(forResource: "image", withExtension: "jpg"),
            let imageAttachment = try? UNNotificationAttachment(identifier: "ImageAttachment", url: imageUrl, options: nil) {
            content.attachments.append(imageAttachment)
        }
        
        // 5秒後に発火するようにRequestを作成してUNUserNotificationCenterに追加
        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
        let request = UNNotificationRequest(identifier: "AttachmentNotification", content: content, trigger: trigger)
        UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
```

結果

![IMG_2036.jpg](https://qiita-image-store.s3.amazonaws.com/0/49151/2bf2f12d-e269-eeb4-f1d4-ba6b12518030.jpeg "IMG_2036.jpg")


左スワイプから表示を選択する（若しくはForceTouch）と

![IMG_2037.jpg](https://qiita-image-store.s3.amazonaws.com/0/49151/dd2b3ecb-2617-dce8-6758-1172fa9aebd7.jpeg "IMG_2037.jpg")


こうなります。

動画をコンテンツとして指定した場合は
![IMG_2038.jpg](https://qiita-image-store.s3.amazonaws.com/0/49151/78ad9dab-24dc-40f2-fa27-737d7b62a934.jpeg "IMG_2038.jpg")

こんな感じで通知センターで動画の再生ができるようになりました。

## 詳細
詳細と言いつつやっていることはUNNotificationAttachmentをUNMutableNotificationContentのattachmentsに追加しているだけです。

```swift
        if let imageUrl = Bundle.main.url(forResource: "image", withExtension: "jpg"),
            let imageAttachment = try? UNNotificationAttachment(identifier: "ImageAttachment", url: imageUrl, options: nil) {
            content.attachments.append(imageAttachment)
        }
```

簡単ですね！

### UNNotificationAttachement
UNNotificationAttachmentはidとメディアコンテンツのパスを指定することで生成します。
optionsには以下のキーが指定可能です。
#### ・UNNotificationAttachmentOptionsTypeHintKey
メディアコンテンツのタイプを指定する。
このキーがない時は、urlで渡したURLの拡張子から自動で判定される。
#### ・UNNotificationAttachmentOptionsThumbnailHiddenKey
メディアコンテンツの非表示フラグ。（DefaultではNO）
trueを指定すると通知センターにサムネイル表示されなくなる。（詳細ではコンテンツが表示される）
true指定時は以下のようにNSNumberで指定する必要があります。

```
[UNNotificationAttachmentOptionsThumbnailHiddenKey:NSNumber(value:true)]
```
#### ・UNNotificationAttachmentOptionsThumbnailClippingRectKey
サムネイルに表示する画像の範囲を指定します。
Valueには0.0〜1.0の範囲で表示したい領域のCGRectを指定します。
[こちら](https://developer.apple.com/reference/usernotifications/unnotificationattachmentoptionsthumbnailclippingrectkey)では
> For example, specifying an origin of (0.25, 0.25) and a size of (0.5, 0.5) defines a clipping rectangle that shows only the center portion of the image.
との記載があるので

```
[UNNotificationAttachmentOptionsThumbnailClippingRectKey:CGRect(x:0,y:0,width:1,height:1).dictionaryRepresentation]
```
こう指定してあげれば画像が全て表示されると思ったのですがうまくいきません。。。
どこが間違っているか教えて頂けるとありがたいです。。。

#### ・UNNotificationAttachmentOptionsThumbnailTimeKey
メディアコンテンツにアニメーション画像、動画を指定した際、サムネイルに表示する秒数を指定できます。
アニメーション画像の際はサムネイルにするフレームを指定して

```
// 1フレーム目をサムネに使用
[UNNotificationAttachmentOptionsThumbnailTimeKey:NSNumber(value:1)]
```

動画の際は

```
// 1秒をサムネに使用
[UNNotificationAttachmentOptionsThumbnailTimeKey:CMTimeCopyAsDictionary(CMTimeMake(1, 1), kCFAllocatorDefault)]
```