new notification api in ios 10

50
Copyright © Up-frontier, Inc. All rights reserved. New Notification API in iOS 10 1

Upload: gaprot

Post on 08-Jan-2017

100 views

Category:

Mobile


0 download

TRANSCRIPT

Copyright © Up-frontier, Inc. All rights reserved.

New Notification API in iOS 10

1

Copyright © Up-frontier, Inc. All rights reserved.

アジェンダ• 新 API でローカル通知

• Media Attachment

• Notification Content Extension

• Notification Service Extension

2

Copyright © Up-frontier, Inc. All rights reserved.

アジェンダ• 新 API でローカル通知

• Media Attachment

• Notification Content Extension

• Notification Service Extension

3

Copyright © Up-frontier, Inc. All rights reserved.

ローカル通知⽅法1. コンテンツを作って

2. トリガーを設定して

3. センターにリクエスト

4

Copyright © Up-frontier, Inc. All rights reserved.

ローカル通知⽅法1. コンテンツを作って

2. トリガーを設定して

3. センターにリクエスト

5

Copyright © Up-frontier, Inc. All rights reserved.

コンテンツlet content = UNMutableNotificationContent() content.title = "Title" content.subtitle = "Subtitle" content.body = "Body" content.categoryIdentifier = "sample-category"

6

Copyright © Up-frontier, Inc. All rights reserved.

コンテンツlet content = UNMutableNotificationContent() content.title = "Title" content.subtitle = "Subtitle" content.body = "Body" content.categoryIdentifier = "sample-category"

7

Copyright © Up-frontier, Inc. All rights reserved.

コンテンツlet content = UNMutableNotificationContent() content.title = "Title" content.subtitle = "Subtitle" content.body = "Body" content.categoryIdentifier = "sample-category"

8

Action や、カスタム UI など 識別に使⽤

Copyright © Up-frontier, Inc. All rights reserved.

ローカル通知⽅法1. コンテンツを作って

2. トリガーを設定して

3. センターにリクエスト

9

Copyright © Up-frontier, Inc. All rights reserved.

トリガーUNNotificationTrigger

10

Copyright © Up-frontier, Inc. All rights reserved.

トリガーUNNotificationTrigger

11

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

Copyright © Up-frontier, Inc. All rights reserved.

リクエストlet id = "sample-\(Date().timeIntervalSince1970)"

let request = UNNotificationRequest( identifier: id, content: content, trigger: intervalTrigger

) center.add(request) { error in

if let error = error { print("Error on requesting notification: \(error)")

} print("Finish requesting notification: \(id)")

}

12

Copyright © Up-frontier, Inc. All rights reserved.

リクエストlet id = "sample-\(Date().timeIntervalSince1970)"

let request = UNNotificationRequest( identifier: id, content: content, trigger: intervalTrigger

) center.add(request) { error in

if let error = error { print("Error on requesting notification: \(error)")

} print("Finish requesting notification: \(id)")

}

13

トリガのセット

Copyright © Up-frontier, Inc. All rights reserved.

リクエストlet id = "sample-\(Date().timeIntervalSince1970)"

let request = UNNotificationRequest( identifier: id, content: content, trigger: intervalTrigger

) center.add(request) { error in

if let error = error { print("Error on requesting notification: \(error)")

} print("Finish requesting notification: \(id)")

}

14

identifier: 識別⼦、更新・削除に利⽤ contents: 通知本体

trigger: 発⽕タイミング

Copyright © Up-frontier, Inc. All rights reserved.

リクエストlet id = "sample-\(Date().timeIntervalSince1970)"

let request = UNNotificationRequest( identifier: id, content: content, trigger: intervalTrigger

) center.add(request) { error in

if let error = error { print("Error on requesting notification: \(error)")

} print("Finish requesting notification: \(id)")

}

15

Notification Centerに追加で完了

Copyright © Up-frontier, Inc. All rights reserved.

アジェンダ• 新 API でローカル通知

• Media Attachment

• Notification Content Extension

• Notification Service Extension

16

Copyright © Up-frontier, Inc. All rights reserved.

Media Attachment

• 通知領域で様々なメディアファイルを表⽰する

17

Copyright © Up-frontier, Inc. All rights reserved.

メディア

18

画像jpg, png, gif

⾳声mp3, mp4

動画mp4, avi

Copyright © Up-frontier, Inc. All rights reserved.

メディア1. 通知内容を作って

2. トリガーを設定して

3. センターにリクエスト

19

Copyright © Up-frontier, Inc. All rights reserved.

メディア1. 通知内容を作って

2. トリガーを設定して

3. センターにリクエスト

20

Copyright © Up-frontier, Inc. All rights reserved.

メディア1. 通知内容を作って

2. トリガーを設定して

3. センターにリクエスト

21

ここで設定する

Copyright © Up-frontier, Inc. All rights reserved.

UNNotificationAttachment guard let imageURL = R.file.sampleJpg() else {

print("Could not instantiate file URL!”) return

} let content = defaultContent do {

let attachment = try UNNotificationAttachment( identifier: "sample-cat", url: imageURL, options: nil

) content.attachments = [attachment]

} catch(let error) { print("Could not instantiate attachment: \(error)")

}

22

Copyright © Up-frontier, Inc. All rights reserved.

UNNotificationAttachment guard let imageURL = R.file.sampleJpg() else {

print("Could not instantiate file URL!”) return

} let content = defaultContent do {

let attachment = try UNNotificationAttachment( identifier: "sample-cat", url: imageURL, options: nil

) content.attachments = [attachment]

} catch(let error) { print("Could not instantiate attachment: \(error)")

}

23

画像の設定 UNNotificationAttachmentを使う

Copyright © Up-frontier, Inc. All rights reserved.

UNNotificationAttachment guard let imageURL = R.file.sampleJpg() else {

print("Could not instantiate file URL!”) return

} let content = defaultContent do {

let attachment = try UNNotificationAttachment( identifier: "sample-cat", url: imageURL, options: nil

) content.attachments = [attachment]

} catch(let error) { print("Could not instantiate attachment: \(error)")

}

24

コンテンツに指定

Copyright © Up-frontier, Inc. All rights reserved.

アジェンダ• 新 API でローカル通知

• Media Attachment

• Notification Content Extension

• Notification Service Extension

25

Copyright © Up-frontier, Inc. All rights reserved.

Notification Content Extension

• オリジナルUIの通知を作成する

26

Copyright © Up-frontier, Inc. All rights reserved.

ターゲット• Notification Content Extension

27

Copyright © Up-frontier, Inc. All rights reserved.

カスタム UI• Storyboard を使って UI を構築

28

Copyright © Up-frontier, Inc. All rights reserved.

NotificationViewControllerclass NotificationViewController : UIViewController , UNNotificationContentExtension { @IBOutlet weak var mapView: MKMapView! override func viewDidLoad() { super.viewDidLoad() } func didReceive(_ notification: UNNotification) { let content = notification.request.content if let lat = content.userInfo["latitude"] as? Double, let lon = content.userInfo["longitude"] as? Double { putPin(into: CLLocationCoordinate2D(latitude: lat, longitude: lon)) } } }

29

Copyright © Up-frontier, Inc. All rights reserved.

NotificationViewControllerclass NotificationViewController : UIViewController , UNNotificationContentExtension { @IBOutlet weak var mapView: MKMapView! override func viewDidLoad() { super.viewDidLoad() } func didReceive(_ notification: UNNotification) { let content = notification.request.content if let lat = content.userInfo["latitude"] as? Double, let lon = content.userInfo["longitude"] as? Double { putPin(into: CLLocationCoordinate2D(latitude: lat, longitude: lon)) } } }

30

MapViewを持った通知

Copyright © Up-frontier, Inc. All rights reserved.

NotificationViewControllerclass NotificationViewController : UIViewController , UNNotificationContentExtension { @IBOutlet weak var mapView: MKMapView! override func viewDidLoad() { super.viewDidLoad() } func didReceive(_ notification: UNNotification) { let content = notification.request.content if let lat = content.userInfo["latitude"] as? Double, let lon = content.userInfo["longitude"] as? Double { putPin(into: CLLocationCoordinate2D(latitude: lat, longitude: lon)) } } }

31

通知が発⽕した時の処理

Copyright © Up-frontier, Inc. All rights reserved.

NotificationViewControllerclass NotificationViewController : UIViewController , UNNotificationContentExtension { @IBOutlet weak var mapView: MKMapView! override func viewDidLoad() { super.viewDidLoad() } func didReceive(_ notification: UNNotification) { let content = notification.request.content if let lat = content.userInfo["latitude"] as? Double, let lon = content.userInfo["longitude"] as? Double { putPin(into: CLLocationCoordinate2D(latitude: lat, longitude: lon)) } } }

32

通知が発⽕した時の処理

通知内容を反映

Copyright © Up-frontier, Inc. All rights reserved.

Info.plist

<dict> <key>NSExtensionAttributes</key> <dict> <key>UNNotificationExtensionCategory</key> <array> <string>customUI</string>

</array> <key>UNNotificationExtensionInitialContentSizeRatio</key> <real>1</real> <key>UNNotificationExtensionDefaultContentHidden</key> <true/>

</dict> <key>NSExtensionMainStoryboard</key> <string>MainInterface</string> <key>NSExtensionPointIdentifier</key> <string>com.apple.usernotifications.content-extension</string>

</dict> 33

Copyright © Up-frontier, Inc. All rights reserved.

Info.plist

<dict> <key>NSExtensionAttributes</key> <dict> <key>UNNotificationExtensionCategory</key> <array> <string>customUI</string>

</array> <key>UNNotificationExtensionInitialContentSizeRatio</key> <real>1</real> <key>UNNotificationExtensionDefaultContentHidden</key> <true/>

</dict> <key>NSExtensionMainStoryboard</key> <string>MainInterface</string> <key>NSExtensionPointIdentifier</key> <string>com.apple.usernotifications.content-extension</string>

</dict> 34

categoryIdentifierと ⼀致している必要あり

Copyright © Up-frontier, Inc. All rights reserved.

Info.plist

<dict> <key>NSExtensionAttributes</key> <dict> <key>UNNotificationExtensionCategory</key> <array> <string>customUI</string>

</array> <key>UNNotificationExtensionInitialContentSizeRatio</key> <real>1</real> <key>UNNotificationExtensionDefaultContentHidden</key> <true/>

</dict> <key>NSExtensionMainStoryboard</key> <string>MainInterface</string> <key>NSExtensionPointIdentifier</key> <string>com.apple.usernotifications.content-extension</string>

</dict> 35

UIの縦横⽐

Copyright © Up-frontier, Inc. All rights reserved.

Info.plist

<dict> <key>NSExtensionAttributes</key> <dict> <key>UNNotificationExtensionCategory</key> <array> <string>customUI</string>

</array> <key>UNNotificationExtensionInitialContentSizeRatio</key> <real>1</real> <key>UNNotificationExtensionDefaultContentHidden</key> <true/>

</dict> <key>NSExtensionMainStoryboard</key> <string>MainInterface</string> <key>NSExtensionPointIdentifier</key> <string>com.apple.usernotifications.content-extension</string>

</dict> 36

デフォルトのタイトル、サブタイトル、コンテンツ

Copyright © Up-frontier, Inc. All rights reserved.

アジェンダ• 新 API でローカル通知

• Media Attachment

• Notification Content Extension

• Notification Service Extension

37

Copyright © Up-frontier, Inc. All rights reserved.

Notification Service Extension

• オリジナルUIの通知を作成する

38

Copyright © Up-frontier, Inc. All rights reserved.

ターゲット• Notification Service Extension

39

Copyright © Up-frontier, Inc. All rights reserved.

NotificationServiceclass NotificationService: UNNotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptContent: UNMutableNotificationContent? override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) if let bestAttemptContent = bestAttemptContent {

// Modify the notification content here... bestAttemptContent.title = "\(bestAttemptContent.title) [modified]" contentHandler(bestAttemptContent) } } override func serviceExtensionTimeWillExpire() {

// Called just before the extension will be terminated by the system. // Use this as an opportunity to deliver your "best attempt" at modified content, // otherwise the original push payload will be used.

if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {

bestAttemptContent.title = "\(bestAttemptContent.title) [Time Expired]" contentHandler(bestAttemptContent) } } }

40

Copyright © Up-frontier, Inc. All rights reserved.

NotificationServiceclass NotificationService: UNNotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptContent: UNMutableNotificationContent? override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) if let bestAttemptContent = bestAttemptContent {

// Modify the notification content here... bestAttemptContent.title = "\(bestAttemptContent.title) [modified]" contentHandler(bestAttemptContent) } } override func serviceExtensionTimeWillExpire() {

// Called just before the extension will be terminated by the system. // Use this as an opportunity to deliver your "best attempt" at modified content, // otherwise the original push payload will be used.

if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {

bestAttemptContent.title = "\(bestAttemptContent.title) [Time Expired]" contentHandler(bestAttemptContent) } } }

41

通知内容を編集

Copyright © Up-frontier, Inc. All rights reserved.

NotificationServiceclass NotificationService: UNNotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptContent: UNMutableNotificationContent? override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) if let bestAttemptContent = bestAttemptContent {

// Modify the notification content here... bestAttemptContent.title = "\(bestAttemptContent.title) [modified]" contentHandler(bestAttemptContent) } } override func serviceExtensionTimeWillExpire() {

// Called just before the extension will be terminated by the system. // Use this as an opportunity to deliver your "best attempt" at modified content, // otherwise the original push payload will be used.

if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {

bestAttemptContent.title = "\(bestAttemptContent.title) [Time Expired]" contentHandler(bestAttemptContent) } } }

42

処理が既定秒数(MAX30秒)を超えると呼ばれる

Copyright © Up-frontier, Inc. All rights reserved.

NotificationServiceclass NotificationService: UNNotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptContent: UNMutableNotificationContent? override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) if let bestAttemptContent = bestAttemptContent {

// Modify the notification content here... bestAttemptContent.title = "\(bestAttemptContent.title) [modified]" contentHandler(bestAttemptContent) } } override func serviceExtensionTimeWillExpire() {

// Called just before the extension will be terminated by the system. // Use this as an opportunity to deliver your "best attempt" at modified content, // otherwise the original push payload will be used.

if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {

bestAttemptContent.title = "\(bestAttemptContent.title) [Time Expired]" contentHandler(bestAttemptContent) } } }

43

サーバからのリモートプッシュを変更する場合 mutable-contetの設定忘れないように

Copyright © Up-frontier, Inc. All rights reserved.

NotificationServiceclass NotificationService: UNNotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptContent: UNMutableNotificationContent? override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) if let bestAttemptContent = bestAttemptContent {

// Modify the notification content here... bestAttemptContent.title = "\(bestAttemptContent.title) [modified]" contentHandler(bestAttemptContent) } } override func serviceExtensionTimeWillExpire() {

// Called just before the extension will be terminated by the system. // Use this as an opportunity to deliver your "best attempt" at modified content, // otherwise the original push payload will be used.

if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {

bestAttemptContent.title = "\(bestAttemptContent.title) [Time Expired]" contentHandler(bestAttemptContent) } } }

44

処理が終わったら速やかに呼ぶ

Copyright © Up-frontier, Inc. All rights reserved.

ありそうな使い⽅• ペイロードにサーバにあるメディアの URL

• ダウンロードして

• Media Attachment

45

Copyright © Up-frontier, Inc. All rights reserved.

リモートコンテンツ 貼り付け

if let bestAttemptContent = bestAttemptContent { guard let urlString = bestAttemptContent.userInfo["remote-url"] as? String, let remoteURL = URL(string: urlString) else { contentHandler(bestAttemptContent) return } download(remoteURL) { url, error in guard let fileURL = url else { print(error) contentHandler(bestAttemptContent) return } do { let attachment = try UNNotificationAttachment( identifier: "remote", url: fileURL ) bestAttemptContent.attachments = [attachment] contentHandler(bestAttemptContent) } catch(let e) { print(e) contentHandler(bestAttemptContent) } } }

46

Copyright © Up-frontier, Inc. All rights reserved.

リモートコンテンツ 貼り付け

if let bestAttemptContent = bestAttemptContent { guard let urlString = bestAttemptContent.userInfo["remote-url"] as? String, let remoteURL = URL(string: urlString) else { contentHandler(bestAttemptContent) return } download(remoteURL) { url, error in guard let fileURL = url else { print(error) contentHandler(bestAttemptContent) return } do { let attachment = try UNNotificationAttachment( identifier: "remote", url: fileURL ) bestAttemptContent.attachments = [attachment] contentHandler(bestAttemptContent) } catch(let e) { print(e) contentHandler(bestAttemptContent) } } }

47

画像のダウンロード 30秒超えるかも

Copyright © Up-frontier, Inc. All rights reserved.

serviceExtensionTimeWillExpireoverride func serviceExtensionTimeWillExpire() { if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { bestAttemptContent.title += " [頑張ったけれどダメだったよ]" contentHandler(bestAttemptContent) } }

48

Copyright © Up-frontier, Inc. All rights reserved.

serviceExtensionTimeWillExpireoverride func serviceExtensionTimeWillExpire() { if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { bestAttemptContent.title += " [頑張ったけれどダメだったよ]" contentHandler(bestAttemptContent) } }

49

サーバからのリモートプッシュの内容を 変更しない場合

もとのペイロードのまま表⽰されてしまうので注意

Copyright © Up-frontier, Inc. All rights reserved.

まとめ

• 新 API でローカル通知

• Media Attachment

• Notification Content Extension

• Notification Service Extension

50