そういえば1ヶ月ほどブログの更新止めちゃってました。お久しぶりです。
WWDC2016の発表を現地…ではなくweb上で色々情報をキャッチアップしてて、その中で 「UserNotifications Framework」 が気になったのでざっくり触ってみました。
今回は、通知(ローカル通知)にattachment
で任意の画像や動画を付けられるようなのでそれを試してみました。
実行環境
- Xcode8 beta (Swift 3.0 preview-1)
情報としては、Apple Developerで公開されている情報を基にしています。
また、まだBeta段階ですので、今後変わる可能性はあります。スクリーンショットは掲載しておりません。
通知に画像を付けてみる
例えば、Project内に追加した、 “img.png” という画像を通知に付加してみます。
contentを作成する
まず、通知の内容を決める、contentを作成します。
contentは、UNMutableNotificationContent
という型になっています。ちなみに、UNNotificationContent
は基本的には直接インスタンスを作ることはせず、
このUNMutableNotificationContent
を使います。
let content = UNMutableNotificationContent()
content.title = "SampleNotification"
content.body = "!!!"
content.badge = 1
content.sound = UNNotificationSound.default()
こんな感じで、title、body,badge,soundを必要に応じてセットします。
attachmentを作成する
次に、先ほど作ったcontentに登録するattachment
を作成します。
作成したあとは、content.attachments
に代入します。
attachmentの型は、UNNotificationAttachment
です。
// attachmentの追加
let attachmentIdentifier = "SampleAttachment"
if let
url = Bundle.main().urlForResource("img", withExtension: "png"),
attachment = try? UNNotificationAttachment(identifier: attachmentIdentifier, url: url, options: nil)
{
content.attachments = [attachment]
}
ここでは、try?
を使って、UNNotificationAttachment
のイニシャライザの返すエラーを流していますが、必要があればtry
でキャッチすると良いでしょう。
また、地味にSwift3.0からは、NSURL→ URL 、NSBundle→ Bundle に変わっているので注意です。
ちなみに、ここで指定できるのはfileURL
となっているので、ダウンロードして表示…ということはできないようです。
triggerを指定する
通知を発火する条件(trigger)を作成します。
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false)
ここでは 3 秒後に発火するようにします。
NotificationCenterにaddする
ここまできたら、UNNotificationRequest
型のrequestを追加し、UNUserNotificationCenterにrequestを追加します。
let requestIdentifier = "SampleNotificationRequest"
let request = UNNotificationRequest(identifier: requestIdentifier,
content: content,
trigger: trigger)
// 通知の登録
UNUserNotificationCenter.current().add(request) { _ in
}
実行してみる
実行してみると、3秒後に通知が発火し、通知バナーに設定したcontentが表示されます。
画像は右側にサムネイルとして小さく表示されます。
通知バナーを下にスワイプするか、長押しすることで、画像を大きく見ることができます。
(まだbetaなので、スクショは貼らないでおきます。)
また、 動画 を指定することもでき、動画の場合は
- 通知に表示するサムネイルの画像を動画のどの部分を使うかの指定
- 通知を長押し大きく表示した状態で、動画を再生
が可能です。
attachmentのオプション
オプションは4つあり、UNNotificationAttachmentのイニシャライザに、optionsとして[String: AnyObject]型で渡して指定することができます。
もちろんnilでも問題ありません。
-
UNNotificationAttachmentOptionsTypeHintKey
→attachmentのタイプを指定することができます。指定しない場合は、URLで渡すfileURLのextensionから判断します。 -
UNNotificationAttachmentOptionsThumbnailHiddenKey
→通知バナーに出るサムネイルを非表示にするかどうか指定できます。指定しない場合はhidden=NO
となります。 -
UNNotificationAttachmentOptionsThumbnailClippingRectKey
→attachmentのサムネイルのクリップ領域を指定できます -
UNNotificationAttachmentOptionsThumbnailTimeKey
→動画のどの部分をサムネイルにするか、時間を指定します。
さいごに
ここまでをまとめたソースを以下に貼り付けます。
そのまま実行できるようにしてあります。
import Foundation
import UIKit
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let options: UNAuthorizationOptions = [.alert, .badge, .sound]
// 通知を許可するかどうかのアラートを出す
UNUserNotificationCenter.current().requestAuthorization(options) { granted, error in
if granted {
// ...
}
}
//デリゲートの登録
UNUserNotificationCenter.current().delegate = self
// 通知用のcontentの作成
let content = UNMutableNotificationContent()
content.title = "Sample Notification"
content.body = "!!!"
content.badge = 1
content.sound = UNNotificationSound.default()
// attachmentの追加
let attachmentIdentifier = "SampleAttachment"
if let
url = Bundle.main().urlForResource("img", withExtension: "png"),
attachment = try? UNNotificationAttachment(identifier: attachmentIdentifier, url: url, options: nil)
{
content.attachments = [attachment]
}
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false)
let requestIdentifier = "SampleNotificationRequest"
let request = UNNotificationRequest(identifier: requestIdentifier,
content: content,
trigger: trigger)
// 通知の登録
UNUserNotificationCenter.current().add(request) { _ in
}
return true
}
}
// MARK: - UNUserNotificationCenterDelegate
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
// フォアグラウンドでも通知バナーを出す
completionHandler([.alert, .sound, .badge])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
completionHandler()
}
}
余談
Advanced Notifications見ててExtension試してみたくなった…。
(おそらく)、サーバーから受け取るpayloadに関してextensionをかますことができて
- payloadから通知を発行するときのカスタムServiceExtensionの作成
- カスタムなNotification UIの作成
ができるようなので、iOS10標準のカレンダーアプリやマップ、メッセージアプリのような事もできそうだし、
カスタムServiceExtensionならwebから画像をダウンロードしてローカルに保存してからattachmentに指定できそう?だし、やれる幅は広がりそう。。
FireBaseあたり登録して、試してみたいところ。