iOS10.0 UserNotification 介绍
iOS10 中统一了本地推送和远程推送的 API,在 UserNotifications.framework 来统一处理与推送相关任务,并增加了图片、音频、视频,自定义通知 UI 等新特性。
回顾
推送的过程:app 向 apple 服务器申请注册通知,apple 服务器再向 APNs 服务器申请 token,APNs 将 token 发送给 app。app 保存这个 token 到个人服务器。在个人服务器根据 token 发送推送时,先将 payload 发送到 APNs,① 然后 APNs 根据 token 下发到对应的 app
我的理解:① iOS10 中 Service Extension & Content Extension 是在这里处理完之后再转发出去。
1 | { |
通知界面
页面变成如下图所示远角矩形,界面的元素有 Title、subTitle、body等,对于用户操作加了 3D Touch、Action。
多媒体
iOS10 中通知不再仅仅是一行文字这么简单,在此版本加入了图片、音频、视频这样的多媒体。对于手机碎片化时间有了更好的诠释。当然对于多媒体的大小是有限制的,对于这些多媒体的加载时间大概在 30s 左右,远程下载的多媒体下载结束之后由系统来管理,当然也可以通过 UserNotificationCenter 来管理。
多媒体类型 | 限制大小 |
---|---|
图片 | 10M |
音频 | 5M |
视频 | 50M |
1.创建 UNNotificationCategory 对象
1 | let myCatrgory: UNNotificationCategory = { |
以上代码也就是定义了一种 category 的 Action 的特征,定义的 Action 在 Appdelegate 中可以做出相应的处理。并注册到 UNUserNotificationCenter 中。此时可以通过通知发送的 payload 中的字段来控制显示哪个 category。
1 | { |
以上的 payload 就是指定 myCatrgory 这个类型。到此一个简单的推送就完成了。
2.初始化 UNNotificationAttachment 对象
1 | let attachment = UNNotificationAttachment(identifier: "identifier", url: url, options: nil) |
- identifier:是对 attachment 的唯一标示
- url:attachment 资源的链接
- options:attachment 一些可选项
比如 .ThumbnailClippingRectKey
表示获取一个缩略图。
3.带多媒体的推送
1 | if #available(iOS 10.0, *) { |
以上代码涉及到 UNTimeIntervalNotificationTrigger 触发器,UNNotificationRequest 通知请求,UNMutableNotificationContent 通知内容。
其中 UNTimeIntervalNotificationTrigger 是 UNNotificationTrigger 抽象类的一个子类,UNNotificationTrigger 一共有3个子类:
- UNCalendarNotificationTrigger 按日期推送
- UNLocationNotificationTrigger 按地点推送
- UNTimeIntervalNotificationTrigger 按时间推送
UNMutableNotificationContent 它相当于payload 的一个对象但是比 payload 内容要丰富。值得注意的是 userInfo 属性,一个类似字典并且其中的内容完全是由开发者来自定义的,大大提高了使用的空间,此时推送可以做更多的事情。
UNNotificationRequest 将 trigger、content 包装一层发送给 UNUserNotificationCenter 来完成本地推送。
3.带多媒体的远程推送
此时就需要用到 UNNotificationServiceExtension 应用扩展,通过在 payload 中增加 mutable-content
字段来触发改扩展。
1 | { |
当推送达到 app 时,会启动扩展并回调 didReceive 方法。在该方法里面可以对推送的 UNMutableNotificationContent 做出相应的修改。在 didReceive 回调方法中的 request 包含了推送的具体信息,可以通过其 userInfo 属性来解析出多媒体的 url,当然也可以去读取本地资源来显示。
从本地读取资源:
1 | let imageURL = Bundle.main.url(forResource: "lufei", withExtension: "jpg") |
值得注意的是这里 Bundle 指的是扩展的沙盒,不是 app 的沙盒,所以资源的路径要正确。
读取远程的资源和本地资源相比多一步下载保存的操作:
1 | private func downloadAndSave(url: URL, handler: @escaping (_ localURL: URL?) -> Void) { |
得到本地的 url 之后操作其实就一样了,都是通过 url 来生成一个 UNNotificationAttachment 对象。一切都操作完之后将这个 UNMutableNotificationContent 对象返还 contentHandler(bestAttemptContent)
自定义界面
iOS10 除了显示 Title、subTitle、body 之外,通过 3D Touch 来显示界面
其中上面的黄色区域可以理解成一个 ViewController 操作,下面绿色部分就是 Title 之类的显示内容。这部分是可以隐藏的。在扩展的目录下的 info.plist 编辑一些界面相关的东西。
- UNNotificationExtensionCategory 触发 Extension 的 category 这里需要在注册才能有效的触发 字符串类型
- UNNotificationExtensionInitialContentSizeRatio 上图黄色区域的长宽比,float 类型
- UNNotificationExtensionDefaultContentHidden 默认内容是否隐藏,Bool 类型
总结
在 iOS10 中的这次推送的重构,方便了开发者对推送的集成。较高程度的自定义 UI 和多媒体增加了推送的趣味性。接下来赶快去集成吧~
参考
后记
写的不准确的地方,欢迎拍砖~
demo 地址