WWDC 2018:iOS 12 通知的新特性

Session 710 : What’s New in User Notificationsswift

iOS 10 新增的 UserNotifications.framework 用一套易用的接口替换了以前版本杂乱的接口,是一次通知接口的大重构。而 iOS 12 则从用户体验的角度为通知带来了诸如通知分类等便捷的新特性, 通知内容扩展也在这次更新中得到了更强的交互能力。本文也从这两个方面对 iOS 12 通知特性的变动进行介绍。安全

新增特性

1. 应用通知分组( Grouped Notifications )

iOS 12 中同一类型的通知会被合成一个通知组,用户能够经过点击通知组展开组里的全部通知。 markdown

通知分组使用两种分组方式:自动分组( 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",
        }
    }
}
复制代码

用户能够在通知管理页面对通知分组进行管理:app

  • 自动( Automatic )
  • 按应用( By App )
  • 关闭( Off ) 注:若是用户选择了 按应用 分组,系统会无视你设定的线程标识只经过 bundle id 对通知进行分组。

2. 通知中心新增通知管理界面

因为如今的用户管理单个应用通知设置的入口太深,iOS 12 推出了全新的推送管理页面以便用户更快捷的操做。 框架

在新的通知管理页面中咱们能够看到两个明显的按钮:隐式推送( Deliver Quietly ) 和 关闭( Turn Off ) 。 隐式推送(根据用户行为有时展现为显式推送)是 iOS 12 为方便用户对通知设置的两种便捷模式之一:

  • 隐式推送(Deliver Quietly) 隐式推送只会显示在通知中心,不会带有声音提醒,应用角标。
  • 显式推送(Deliver Prominently) 显示推送会开启全部的通知选项。

展现管理页面有 3 种方式:ide

  • 左滑通知,点击 管理 按钮
  • 进入通知详情页面,点击右上角的 更多 按钮
  • 系统根据用户行为自动的给出提示,点击 管理 按钮

自定义通知设置页面( Custom Settings )

因为新的通知管理页面也支持用户关闭通知提示,App 能够为通知提供更详细的管理页面引导用户关闭部分他们不但愿收到的推送而不是关闭全部。当用户点击通知设置页面对应的按钮时,iOS 12 提供了新的代理方法获取这个事件并处理。 注:代理中 notification 参数是个 optional ,当用户从设置页面点击管理通知时这个参数会是 nil 。oop

import UIKit
import UserNotifications

class AppDelegate: UIApplicationDelegate, UNUserNotificationCenterDelegate {

    func userNotificationCenter(_ center: UNUserNotificationCenter, openSettingsFor notification: UNNotification? ) {

    }

}
复制代码

3. 无需用户受权也能给用户推送的新机制:临时受权( Provisional Authorization )

iOS 12 提供了一种新的通知受权机制:临时受权。这种机制不会给用户受权的弹窗而直接尝试给用户推送,须要注意的是临时受权推送的消息只会以隐式推送的方式展现给用户。 post

在代码中咱们只须要设置参数 provisional 就能使用这种机制。ui

let notificationCenter = UNUserNotificationCenter.current()

notificationCenter.requestAuthorization(options:[.badge, .sound, .alert, .provisional]) {

}
复制代码

4. 勿扰模式下依然能够收到的通知:重要提醒( Critical Alerts )

当咱们在开会或者参与一些很重要的活动时,一般会开启勿扰模式或者关闭铃声,但这个操做有可能会让咱们错过一些关键的通知。 iOS 12 中加入的重要提醒可以无视勿扰模式和铃声开关的限制,收到这类通知时会伴随一个系统或 App 设定的提示音。须要推送重要提醒的应用须要前往 developer.apple.com/contact/req… 得到受权。spa

注:所谓的重要提醒是指那些须要用户即刻作出反应的通知,例如与医疗和健康相关的通知,与家庭安全相关的通知,与公共安全相关的通知等。

通知设置页面重要提醒的开关区别于普通的通知开关

系统容许只接收重要提醒

在代码中咱们须要设置参数 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 专题目录 - 简书