Session 710 : What’s New in User Notifications
iOS 10 新增的 UserNotifications.framework 用一套易用的介面替換了之前版本雜亂的介面,是一次通知介面的大重構。而 iOS 12 則從使用者體驗的角度為通知帶來了諸如通知分類等便捷的新特性, 通知內容擴充套件也在此次更新中獲得了更強的互動能力。本文也從這兩個方面對 iOS 12 通知特性的變更進行介紹。
新增特性
1. 應用通知分組( Grouped Notifications )
iOS 12 中同一型別的通知會被合成一個通知組,使用者可以通過點選通知組展開組裡的所有通知。
通知分組使用兩種分組方式:自動分組( Automatic grouping ) 和執行緒標識( Thread identifier )。開發者不需要對自動分組做額外的操作,系統會根據 App 的 bundle id 對推送進行分組。如果需要對通知做更細緻的分組就需要用上執行緒標識了。// 本地通知
let content = UNMutableNotificationContent()
content.title = "New Photo"
content.body = "Jane Doe posted a new photo"
// 自定義標識
content.threadIdentifier = "thread-identifier"
// 遠端通知
{
"aps" : {
"alert" : {
"title" : "New Photo",
"body" : "Jane Doe posted a new photo",
"thread-id" : "thread-identifier",
}
}
}
複製程式碼
使用者可以在通知管理頁面對通知分組進行管理:
- 自動( Automatic )
- 按應用( By App )
- 關閉( Off ) 注:如果使用者選擇了 按應用 分組,系統會無視你設定的執行緒標識只通過 bundle id 對通知進行分組。
2. 通知中心新增通知管理介面
由於現在的使用者管理單個應用通知設定的入口太深,iOS 12 推出了全新的推送管理頁面以便使用者更快捷的操作。
在新的通知管理頁面中我們可以看到兩個明顯的按鈕:隱式推送( Deliver Quietly ) 和 關閉( Turn Off ) 。 隱式推送(根據使用者行為有時展示為顯式推送)是 iOS 12 為方便使用者對通知設定的兩種便捷模式之一:- 隱式推送(Deliver Quietly) 隱式推送只會顯示在通知中心,不會帶有聲音提醒,應用角標。
- 顯式推送(Deliver Prominently) 顯示推送會開啟所有的通知選項。
展示管理頁面有 3 種方式:
- 左滑通知,點選 管理 按鈕
- 進入通知詳情頁面,點選右上角的 更多 按鈕
- 系統根據使用者行為自動的給出提示,點選 管理 按鈕
自定義通知設定頁面( Custom Settings )
由於新的通知管理頁面也支援使用者關閉通知提示,App 可以為通知提供更詳細的管理頁面引導使用者關閉部分他們不希望收到的推送而不是關閉所有。當使用者點選通知設定頁面對應的按鈕時,iOS 12 提供了新的代理方法獲取這個事件並處理。 注:代理中 notification 引數是個 optional ,當使用者從設定頁面點選管理通知時這個引數會是 nil 。
import UIKit
import UserNotifications
class AppDelegate: UIApplicationDelegate, UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, openSettingsFor notification: UNNotification? ) {
}
}
複製程式碼
3. 無需使用者授權也能給使用者推送的新機制:臨時授權( Provisional Authorization )
iOS 12 提供了一種新的通知授權機制:臨時授權。這種機制不會給使用者授權的彈窗而直接嘗試給使用者推送,需要注意的是臨時授權推送的訊息只會以隱式推送的方式展示給使用者。
在程式碼中我們只需要設定引數 provisional 就能使用這種機制。
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.requestAuthorization(options:[.badge, .sound, .alert, .provisional]) {
}
複製程式碼
4. 勿擾模式下依然可以收到的通知:重要提醒( Critical Alerts )
當我們在開會或者參與一些很重要的活動時,通常會開啟勿擾模式或者關閉鈴聲,但這個操作有可能會讓我們錯過一些關鍵的通知。 iOS 12 中加入的重要提醒能夠無視勿擾模式和鈴聲開關的限制,收到這類通知時會伴隨一個系統或 App 設定的提示音。需要推送重要提醒的應用需要前往 developer.apple.com/contact/req… 獲得授權。
注:所謂的重要提醒是指那些需要使用者即刻做出反應的通知,例如與醫療和健康相關的通知,與家庭安全相關的通知,與公共安全相關的通知等。
通知設定頁面重要提醒的開關區別於普通的通知開關
系統允許只接收重要提醒在程式碼中我們需要設定引數 criticalAlert ,使用者會看到單獨的重要提醒授權
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.requestAuthorization(options:[.badge, .sound, .alert, .criticalAlert]) {
}
複製程式碼
推送重要提醒通知和普通通知的區別在於提示音
// 本地重要提醒
let content = UNMutableNotificationContent()
content.title = "WARNING: LOW BLOOD SUGAR"
content.body = "Glucose level at 57."
content.categoryIdentifier = "low-glucose—alert"
// 使用系統預設的重要提醒音
content.sound = UNNotificationSound.defaultCritical
// 使用自定義的重要提醒音
content.sound = UNNotificationSound.criticalSoundNamed(@"warning-sound" withAudioVolume: 1.00)
// 遠端重要提醒
{
"aps" : {
"sound" : {
"critical": 1,
"name": "warning-sound.aiff",
"volume": 1.0
}
}
}
複製程式碼
舊有特性升級
1. 通知內容擴充套件升級,更具互動性( Notification Content Extensions )
Notification Content Extensions 是 iOS 10 新增的通知擴充套件之一,在 iOS 12 中得到了增強,不熟悉的同學可以通過喵神的文章瞭解下: 活久見的重構 - iOS 10 UserNotifications 框架解析。
通知動作( notification actions )
iOS 12 提供了新的 API 來解決動作當前動作存在的兩個問題:
- 無法動態修改
- 與 category 聯絡緊密
extension NSExtensionContext {
@available(iOS 12.0, *)
var notificationActions: [UNNotificationAction]
}
複製程式碼
notificationActions 屬性允許你獲取當前擴充套件的動作,更新新的動作。
class NotificationViewController: UIViewController, UNNotificationContentExtension {
func didReceive(_ response: UNNotificationResponse, completionHandler completion:
(UNNotificationContentExtensionResponseOption) -> Void) {
if response.actionIdentifier == "like-action" {
// Update state...
let unlikeAction = UNNotificationAction(identifier: "unlike-action", title: "Unlike", options: [])
let currentActions = extensionContext?.notificationActions
let commentAction = currentActions![1]
let newActions = [ unlikeAction, commentAction ]
extensionContext?.notificationActions = newActions
}
}
}
複製程式碼
通知擴充套件介面新增可互動狀態( User interaction )
Content view 是預設不可互動的,iOS 12 想要將其設定為可互動的狀態,只需要在 plist 中 將 UNNotificationExtensionUserInteractionEnabled 設定為 true 即可。通過 API 呼叫啟動 App( Launch application )
某些場景下我們會在通知內容擴充套件中加入展示所有評論的功能,並且展示操作只有在應用內才能完成,iOS 12 提供了一個新的 API 讓我們能通過程式碼啟動 App 。
extension NSExtensionContext {
@available(iOS 12.0, *)
func performNotificationDefaultAction()
}
// Demo: 在 Notification Content Extension 中啟動 App
import UserNotificationsUI
class NotificationViewController: UIViewController, UNNotificationContentExtension {
@IBOutlet var allCommentsButton: UIButton?
...
allCommentsButton?.addTarget(self, action: #selector(launchApp), for: .touchUpInside)
...
@objc func launchApp() {
extensionContext?.performNotificationDefaultAction()
}
}
複製程式碼
當這個 API 被呼叫時, App 會被啟動,並呼叫代理方法:
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
// Handle action response
}
複製程式碼
通過 API 呼叫隱藏通知內容擴充套件介面( Dismiss content extension view )
如果我們想在通知內容擴充套件上增加一個‘喜歡’按鈕,使用者點選後自動關閉當前的擴充套件,新增加的 API 能夠幫助你實現這一功能。
extension NSExtensionContext {
@available(iOS 12.0, *)
func dismissNotificationContentExtension()
}
// Demo: 在通知內容擴充套件中隱藏通知內容擴充套件頁面
import UserNotificationsUI
class NotificationViewController: UIViewController, UNNotificationContentExtension {
@IBOutlet var likeButton: UIButton?
...
likeButton?.addTarget(self, action: #selector(likeButtonTapped), for: .touchUpInside)
...
@objc func likeButtonTapped() {
likedPhoto()
extensionContext?.dismissNotificationContentExtension()
}
}
複製程式碼
需要注意的是,呼叫這個 API 並不會移除那條通知,如果需要移除通知可以呼叫下面的 API
class UNUserNotificationCenter {
func removeDeliveredNotifications(withIdentifiers identifiers: [String])
}
複製程式碼
總結
有 iOS 10 整體通知框架的打底,iOS 12 在通知的使用者體驗上的提升還是挺顯著的,而通知關閉的成本降低勢必需要內容生產方對推送內容更加謹慎,或者為部分推送內容提供關閉的選項。期待在 iOS 12 上看到利用新特性的有趣應用。
檢視更多 WWDC 18 相關文章請前往 老司機x知識小集xSwiftGG WWDC 18 專題目錄 - 簡書