iOS12Notication

前言

在苹果2018年6月新召开的WWDC大会上, 苹果针对iOS12提出了许多新的框架和功能. 具体有什么可以看这里.今天主要就其中Notifications新增的特性做一些了解. 原文中对iOS12推送的描述是这样的:

Notification content app extensions now support user interactivity in custom views. If the content of your app’s notifications needs to prompt user interaction, add controls like buttons and switches.

意思是推送通知的扩展内容支持与用户的交互, Notification Extension是iOS10的时候苹果推出的通知扩展内容,我们可以自定义通知内容的样式,但是是不允许交互的.除此之外, 此次还新增了,推送分组功能,通知中心多了管理功能,还多了几种权限管理的功能. 这是我做的demo的gif,接下来让我们一一摸索下.

ps. 目前工程需要在xcode10之下创建, 所以需要先下载xcode10的beta版,旧版可以与新版本共存,所以问题不大,可以放心下载.

通知分组功能

目前我们收到的推送都是一条一条推过来的, 有时候会密集的收到某个app的多次推送轰炸, 或者是某个人同时发来的很多条消息. 大概为了解决这个痛点, 苹果在iOS12为我们把推送消息进行了分组. 同一类型的通知会被合成一个通知组,用户可以通过点击通知组展开组里的所有通知. 分组方式分为两种:自动分组和线程标识. 分组的效果图如下:

  • 自动分组

    自动分组就是根据app的类型来把不同app的消息分成一组,但是如果你想把自己app的消息也分一下组就用到了另一种方式.

  • 线程标识

    线程标识是根据不同的threadIdentifier来标识不同的分组, 就像我这个例子里的, 我创建了两个分组,一组法国一组克罗地亚.当然显示的这个是根据summaryArgument来的和定义的threadIdentifier并无关系.

下面直接上代码,首先,我们需要先向用户进行权限申请, 也非常简单.

1
2
3
4
5
6
7
8
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.requestAuthorization(options: [.badge,.alert,.sound]) { (tag, error) in
if tag {
print("允许")
}else {
print("被拒: \(error?.localizedDescription ?? "").")
}
}

不过需要注意的是, 在iOS12除了原有的badge,alert,sound基础上出了几个新的选项.

  • provisional: 临时授权, 通知会出现在通知中心并在应用图标上出现标记,但不会显示在锁定屏幕上,不会显示横幅,也不会播放声音,之后可以选择正常推送还是继续静默.

  • criticalAlert:重要提醒, 无视勿扰模式和铃声开关的限制,收到这类通知时会伴随一个系统或App设定的提示音 需要获得相应证书授权.

然后第二步, 设置推送的Categories. iOS12之前我们可以通过在Category中添加不同的action, 然后推送的内容下面就会弹出这些action来响应用户操作,但是我们的扩展内容支持交互了,就不需要添加action. 点进UNNotificationCategory的头文件,会发现现在category的init方法中多了一个带categorySummaryFormat参数的方法.
其实这个就是设置我上面例子中的1 moer notifications from

1
2
3
4
5
6
7
8
let summaryFormat = "%u 条更多消息~~~"
let debitOverdraftNotifCategory = UNNotificationCategory(identifier: "FNNotification",
actions: [],
intentIdentifiers: [],
hiddenPreviewsBodyPlaceholder: nil,
categorySummaryFormat: summaryFormat,
options: [])

设置完categorySummaryFormat之后推送的消息会按照我们的设置来, 像这样

当然还有另一种定制方式,定制完会像上面显示的一样,这个下面会提到.

接下来就是创建一个本地通知然后发送,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
guard settings.authorizationStatus == .authorized else { return }
var names = ["法国", "法国","法国","克罗地亚","克罗地亚"]
// 推送2组消息, 一组3条,一组2条
for i in 0...4 {
let content = UNMutableNotificationContent()
content.title = "🍉 西瓜打折啦! 错过等三年!"
content.body = "下拉这个对话框"
content.categoryIdentifier = "FNNotification"
content.sound = UNNotificationSound.default
content.threadIdentifier = names[i] //分组标识符 属于哪个分组
content.summaryArgument = names[i]
/** 设置推送的图片
远程通知需要在推送的payload中指定需要加载的图片资源地址, 也可以是网络地址, 需要下载到本地然后继续设置attachment
*/
if let imageURL = Bundle.main.url(forResource: "image", withExtension: "jpeg"),
let attachment = try? UNNotificationAttachment(identifier: "imageAttachment", url: imageURL, options: nil)
{
content.attachments = [attachment]
}
//创建发送触发
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
//创建发送请求
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
//将请求添加到发送中心
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
}

需要注意的几个点是

  • categoryIdentifier 要与我们上面创建的category的identifier相同,目的是为了之后扩南内容的交互, 苹果原话如下:

Assign a value to this property that matches the identifier property of one of the UNNotificationCategory objects you previously registered with your app. If you assign a string that does not match one of your registered categories, the system displays your notification without custom actions and without routing it through your app extensions.

  • summaryArgument 是iOS12新出的属性,想必你也猜到了,就是上面提到的第二种定制方式.推送的消息会以这个字段显示from *

  • threadIdentifier 就是分组的重点了,这是一个分组标识符, 我们就是通过这个来分组的, 这里我分了两组.


通过上面这些操作, 就可以发送一个带有定制尾巴的分组推送了,当然如果是远程推送的话在payload中设置相应的字段就可以了.需要额外提一下的是,能否分组的终极权限还是在用户手里, 用户可以在设置界面选择是自动,按应用还是关闭.选择按应用之后我们设置的threadIdentifier就不会起作用了.

扩展内容的可交互性

创建Notification Extension,操作方式如下:

  1. File > New > Target

  2. 然后选取Notification Extension

  3. 点击next, 命名, 点击finished

然后在工程目录下会多一个extension, 会自带一个viewController,storyboard和info.plist. 这个viewController就是供我们自定义UI用的.info文件里可以配置一些视图的信息.

不过在自定义之前, 我们还需要了解下Extension的整体结构.

header是app的名字, 底部default是之前设置content中的标题和副标题,中间就是我们可以自定义的部分了.当然底部是可以隐藏掉的, 需要在info里面配置,之后会详细解释.

然后就可以在storyboard中配置自己想要的UI,拖入一些控件然后关联到viewController中.在viewController系统已经帮我们写好了一个didReceive的方法,推送的内容可以在这里接收到.那我们就可以在这里将内容和UI关联起来做一些交互.

1
2
3
func didReceive(_ notification: UNNotification) {
}

做完这些还有最后一步, 就是配置info.plist, 主要是NSExtensionAttributes中的内容.默认的是只有前面两个属性的

  • UNNotificationExtensionCategory(必选) 我们之前设置的category的identifier
  • UNNotificationExtensionInitialContentSizeRatio (必选) 页面的比例系数,通过这个来调整自定义UI的大小
  • UNNotificationExtensionDefaultContentHidden (可选) 是否要隐藏掉最下面的标题栏
  • UNNotificationExtensionUserInteractionEnabled (可选) 是否可以交互
  • UNNotificationExtensionOverridesDefaultTitle (可选) bool值, 可以设置是否自定义title, 原本是显示app的名字,设置yes之后,需要在viewController中重新设置title,然后推送的标题就会是我们设置的推送.

小结

以上基本就是关于iOS12推送新出的一些内容, 主要是分组推送还有扩展内容的可交互性,新增的权限静默推送和重要推送,新增的消息管理方式. 欢迎大家一起交流.

demo已经上传至github,在这里下载, 喜欢的话可以给个小star哦~