iOS 12:通知中的新功能

举行了WWDC会议,仍然有很多报道值得一看。 苹果公司特别关注了一些关键主题。 核心ML,Siri快捷键,当然还有对通知的更改。



由于并非每个人都有足够的空闲时间来浏览文档的丛林(通常会发生这种情况,在beta测试阶段尚无所求),所以我准备了对新功能的回顾,并通过实际实现对材料进行了证实。 阅读,理解并集成到您的应用程序中。


让我们从苹果添加的功能开始。


通知分组


对于实施,不需要做任何事情。 iOS 12将自动为您分组消息。 但是存在与自定义,本地化和分组有关的细微差别,但不是基于应用程序标识符,而是例如取决于发送通知的用户的名称。


此外,如果您要测试通知的分组,请注意-仅当一次无法在屏幕上容纳所有通知时,它们才会开始打包收集。 例如,为此,您需要在iPhone 8的屏幕上放置5条或更多条通知。



为了不使该材料过载,我将这些信息放在单独的文章中


对NSExtensionContext API的更改


下一项是通知的新机会,尤其是NSExtensionContext类。 他负责与小部件Siri交互,播放媒体内容。 我们对通知更感兴趣。 添加了两种方法和一个变量:


var notificationActions: [UNNotificationAction] { get set } 

该变量允许在与通知交互期间替换可用操作集:


 func dismissNotificationContentExtension() func performNotificationDefaultAction() 

方法打开应用程序或隐藏通知。


为了演示可能性,我们将编写一个小应用程序。


首先,添加到发送本地通知的应用程序中:


 let actions = [ UNNotificationAction(identifier: "like-action", title: "Like", options: []), UNNotificationAction(identifier: "open-app", title: "Open App", options: []), UNNotificationAction(identifier: "dismiss", title: "Dismiss", options: []), ] let simpleCategory = UNNotificationCategory(identifier: "category-simple", actions: actions, intentIdentifiers: [], options: []) UNUserNotificationCenter.current().setNotificationCategories([simpleCategory]) 

  • 我们创建一些动作。 标头是一个标识符,使您可以区分处理操作和选项,该标识符传递给初始化程序。 这些选项可能指示完成操作需要用户认证。
  • 我们定义一个带有标识符的类别。 类别标识符允许您以不同的方式处理和显示不同类型的通知。
  • 最后一步是设置通知中心的类别。

第二种方法将在指定的时间段后发送本地通知,以便我们可以最小化应用程序或锁定手机:


 UNUserNotificationCenter.current().getNotificationSettings { (settings) in guard settings.authorizationStatus == .authorized else { return } let content = UNMutableNotificationContent() content.title = "Cat Title" content.subtitle = "Cat Subtitle" content.body = "Cat Body" content.sound = .default content.categoryIdentifier = "category-simple" let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false) let uuid = UUID().uuidString let request = UNNotificationRequest(identifier: uuid, content: content, trigger: trigger) UNUserNotificationCenter.current().add(request, withCompletionHandler: { (error) in }) } 

  • 检查用户是否允许我们发送通知。
  • 我们创建一个带有标题和文本的通知,并指明该通知所属的类别。 在这种情况下,“类别简单”。
  • 3秒后设置触发触发器。
  • 填写发送通知的请求。 在这种情况下,我们使用UUID作为标识符。 如果我们要取消计划的通知,则可能需要此标识符。
  • 将我们的请求添加到通知中心。

接下来,您需要向应用程序添加一个新的Notification Content Extension目标。 它允许您自定义通知的显示和动作的处理。



将创建一个plist文件,ViewController和Storyboard:



在plist文件中,我们对以下键感兴趣:


  • UNNotificationExtensionCategory-将要处理的类别的名称。 和以前一样,指定“简单类别”。
  • UNNotificationExtensionInitialContentSizeRatio-通知的高度与其宽度的比率。 完整显示后,影响通知的大小。
  • UNNotificationExtensionUserInteractionEnabled-启用或禁用与自定义控件的交互。 在我们的情况下,这将是一个带有一颗心的按钮。
  • UNNotificationExtensionDefaultContentHidden-隐藏默认情况下生成的通知内容。

在情节提要中,创建UIImageView,UILabel以显示通知标题以及UIButton与应用程序进行交互。



在View Controller中,我们创建方法来打开应用程序并隐藏通知:


 func openApp() { extensionContext?.performNotificationDefaultAction() } func dismissNotification() { extensionContext?.dismissNotificationContentExtension() } 

我们实现UNNotificationContentExtension协议的方法。


第一个将允许您显示必要的文本:


 func didReceive(_ notification: UNNotification) { self.notificationTitleLabel.text = notification.request.content.body } 

需要第二个来处理UNNotificationAction的操作 。 在相同的方法中,使用extensionContext?.NotificationActions分配替换动作:


 func didReceive(_ response: UNNotificationResponse, completionHandler completion: @escaping (UNNotificationContentExtensionResponseOption) -> Void) { switch response.actionIdentifier { case "like-action": let actions = [ UNNotificationAction(identifier: "1-star", title: "★", options: []), UNNotificationAction(identifier: "2-star", title: "★ ★", options: []), UNNotificationAction(identifier: "3-star", title: "★ ★ ★", options: []), ] extensionContext?.notificationActions = actions case "open-app": openApp() default: dismissNotification() } } 

照常通过IBAction执行心脏抽头:


 @IBAction func defaultButtonTapped(_ sender: UIButton) { openApp() } 


我们启动该应用程序,然后查看得到的结果:


  • 处理来自UIButton的按下
  • 使用UNNotificationAction允许替换可用于交互的选项。

与通知设置的交互


以下创新使您可以将新菜单项添加到通知设置。 当您点击它时,将调用一个可以在应用程序中实现的方法。 例如,用户可以直接从系统设置进入您的应用程序,并且仅包括他真正想要接收的那些通知。 实施需要做什么?


首先,在授权通知时,我们再添加一个参数-includesAppNotificationSettings


 UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .alert, .sound, .providesAppNotificationSettings]) 

其次,我们实现UNUserNotificationCenterDelegate协议的userNotificationCenter(_:openSettingsFor :)方法:


 extension AppDelegate: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, openSettingsFor notification: UNNotification?) { openSettings() } func openSettings() { let storyboard = UIStoryboard(name: "Settings", bundle: nil) let settings = storyboard.instantiateViewController(withIdentifier: "Settings") window?.rootViewController = settings } } 


临时通知


用户并不总是了解他是否要从您的应用程序接收通知。 因此,当您第一次启动该应用程序时,他很难做出这样的选择。 他很有可能拒绝您的提议。 对于这种情况,Apple建议使用临时授权。 当请求授权发送通知时,会添加另一个参数- 临时 。 此类通知的authorizationStatus也会以临时状态进入应用程序。


 UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .alert, .provisional]) 

启动应用程序时,用户将不会收到授权请求。 但是,为了不打扰他,将应用程序放置在所谓的监狱中 。 对于通知,声音,徽章被禁用; 它们仅显示在通知中心中。 它们不会出现在锁定屏幕上或横幅形式。


当用户收到通知时,将出现两个附加按钮。 一个将完全阻止通知或提供设置设置,第二个将您的通知转换为授权状态:



严重警报


最新更改添加了另一种通知- 严重警报 。 这些通知会完全忽略您的手机设置,静音或不打扰模式。 Apple建议在医疗应用中使用它们(例如,设备用户的血糖水平急剧上升),并确保用户在家中或公共场所的安全。


授权请求包含一个特殊字符:



设置中添加了一个新项目,通知屏幕上显示了一个附加图标:



要发送重要通知,您必须在Apple网站上完成应用程序的验证过程。


要使用通知,请使用criticalAlert参数:


 UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .alert, .criticalAlert]) 

然后我们形成通知的内容:


 let content = UNMutableNotificationContent() content.title = "WARNING" content.body = "Storm alert" content.categoryIdentifier = "storm-alert" content.sound = UNNotificationSound.defaultCriticalSound(withAudioVolume: 1.0) 

对于“ 严重警报”,无论用户如何设置都可以指定触发通知的音量。


我希望本文能简化将新通知引入您的应用程序的过程。 如果您无法确定实施的某些阶段,建议您熟悉github上的代码或在注释中提出问题。


您还可以观看有关iOS 10通知的e-Legion文章或WWDC记录的报告- 用户通知中的新增功能。 我们将在9月28日于莫斯科举行的MBLT DEV 2018上讨论创新技术。


祝大家有美好的一天,海豹海豹^ _ ^


UPD:Habré上有关分组通知文章的第二部分

Source: https://habr.com/ru/post/zh-CN416307/


All Articles