下記ブログの転載です
https://rc-code.info/ios/post-61/
iOS12(したがって開発環境はXcode10.0)から Notificationの通知内容上でインターフェースを自由に使うことができる ようになりました。
Notificationの表示コンテンツをカスタマイズする Notification Content Extension 自体はiOS10から利用できましたが、改めて調べたので備忘録。
Notificationのカスタマイズ iOS12
Notification Content Extension とはアプリ内にモジュールを用意しておくことで、アプリのNotification着信時にカスタマイズされたViewControllerを表示させる機能です。


カスタマイズできる事項
- アラートのタイトル、サブタイトル、本文を含むアイテムの配置する
- インタフェース要素を異なるフォントやスタイリングに置き換える
- アプリケーション固有のデータを扱う(たとえば、通知のペイロードで受け取った固有キーから格納されているデータを引き出したり)
- カスタム画像やブランディング要素を含める
Notification Content Extension を使えば モジュール
に対して公開してされているアプリ内の様々なデータや機構を扱えます。
つまり、動的なデータや情報をアプリから取得し、表示要素として扱うことも可能になります。
ただし、相変わらずランタイムを圧迫するような処理(ネットワークからデータを受け取って表示するなど)は控えた方が良さそうです。
公式ドキュメントでは Notification のデリゲート処理に30秒以上かかった場合キャンセルされるとありますので、通信を介する処理などはユーザビリティとしても避けた方が良いかと思います。
Notification Content Extension の使い方!
モジュールの追加
まず、アプリの Target に Notification Content Extension を追加します
下記画像を参考に、TARGETS下の + をクリックしてください。
続いて、下記画像を参考に Notification Content Extension を指定します。
下記の様に、Extension用のモジュールが追加された事を確認しましょう。
Notification カテゴリの設定
Extensionディレクトリに含まれる Info.plist の ExtensionCategory をエクステンションを利用したい場合のカテゴリ名に変更します
上記はカテゴリ名を GENERAL と設定していますが、これによりNotificationで送られてきたペイロードのカテゴリが GENERAL だった場合にエクステンションを利用するようになります。
下記はNotificationをコードから実行する場合のサンプルコードです。
// カテゴリの生成
let category = UNNotificationCategory(identifier: "GENERAL", actions: [], intentIdentifiers: [], options: [])
// UNUserNotificationCenter にカテゴリを登録
UNUserNotificationCenter.current().setNotificationCategories([category])
// Notification の生成
let content = UNMutableNotificationContent()
content.title = title_textField.text
content.body = body_textField.text
content.categoryIdentifier = "GENERAL"
// 発火する時間を設定
let time = TimeInterval(0)
// 発火するためのタイマーを生成
let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: time, repeats: false)
// Notification のリクエストを生成
let request = UNNotificationRequest.init(identifier: "myNotification", content: content, trigger: trigger)
// リクエストを登録
UNUserNotificationCenter.current().add(request)
// 上記処理で、0秒後にカテゴリ "GENERAL" のNotificationが発火します
下記はカテゴリが GENERAL に設定されたDNSのペイロードサンプルです
{
"aps" : {
"category" : "GENERAL"
"alert" : {
"title" : "PushNotification Test",
"body" : "hogehogehoge fugafugafuga"
},
"badge" : 3,
"sound" : "chime.aiff"
}
}
デフォルトコンテンツの表示設定
UNNotificationExtensionDefaultContentHidden を Info.plist の NSExtensionAttributes配下 に追加し、デフォルトの通知コンテンツ(2つ目画像の Default interface 部分)を隠したければ、Boolean = YES を格納します。
インターフェースの操作設定
iOS12 から UNNotificationExtensionUserInteractionEnabled を Info.plist の NSExtensionAttributes配下 に追加し、Boolean = YES を格納するで、CustomViewController で ** switch や button といったインタラクティブなインターフェースを実装する事が出来る **ようになりました。
これを設定しないと、デフォルトで用意されている Button 以外にインターフェースを実装しても反応しません。
デフォルトで用意されているビデオ制御用のインターフェースを利用する場合は下記のような実装になります。
class NotificationViewController: UIViewController, UNNotificationContentExtension {
@IBOutlet weak var emptyView: UIView!
~~~ 省略 ~~~
let mediaPlayPauseButtonType: UNNotificationContentExtensionMediaPlayPauseButtonType = .overlay
var mediaPlayPauseButtonFrame: CGRect {
return CGRect(x: self.view.frame.width / 2 - emptyView.frame.width / 2, y: playerView.frame.height / 2 - emptyView.frame.height / 2, width: emptyView.frame.width, height: emptyView.frame.height)
}
public func mediaPlay() {
~~~ media制御 ~~~
}
public func mediaPause() {
~~~ media制御 ~~~
}
~~~ 省略 ~~~
}
タイトルのカスタマイズ設定
UNNotificationExtensionOverridesDefaultTitle を Info.plist の NSExtensionAttributes配下 に追加し、通知の Title をアプリ名以外に変えたければ、Boolean = YES を格納する
title を変更したい場合は、CustomViewController 内で下記のように実装する。
func didReceive(_ notification: UNNotification) {
self.title = "AAAAAA"
}
これはNotification自体のtitle変更ではなく、CustomViewControllerを開いた際のtitleです。
コンテンツの作成
Extensionディレクトリに含まれる NotificationViewController と MainInterface.storyboard を編集し、表示したいコンテンツを作成します。
末尾に記載したサンプルでは、アプリ内に保存された動画を再生しています。
先に示した画像の右側が、ViewControllerの内容になります。
真ん中の再生マークは iOS12以前で利用するためのデフォルトのインターフェースです。
右下のButtonはiOS12から利用可能になった UNNotificationExtensionUserInteractionEnabled を有効にした際に操作可能になるカスタムViewのサンプルです。
Ex. サンプル
https://github.com/uin010bm/UINNotificationContentAppExtension
Info. ドキュメント
Info. サンプルテスト環境
Mac OS: 10.13.6
Xcode: Version 10.0