通知相关系列文章
iOS10 之前通知使用介绍
[iOS] 通知详解: UIUserNotification
iOS10 相关API
[iOS] 通知详解:iOS 10 UserNotifications API
iOS10 本地/远程通知
[iOS] 通知详解: iOS 10 UserNotifications
iOS10 通知附加包
[iOS] 通知详解: iOS 10 UserNotifications – 附加包Media Attachments
iOS10 自定义UI
[iOS] 通知详解: iOS 10 UserNotifications – 自定义通知UI

无论是远程通知还是本地通知,都可以添加附加包,自己根据文件URL来创建UNNotificationAttachment实例,然后添加到相应的通知请求的UNMutableNotificationContent实例中。区别是获取附件的方式,一般本地通知的附件是放在本地的Bundle中的,只需要在创建本地通知的时候,根据附件的URL创建相应的UNNotificationAttachment即可;远程通知,需要根据远程的通知携带的URL地址,去初始化UNNotificationAttachment,接着就会通过Service Extensions服务来下载这些附件数据,在通知中进行显示。

本地通知添加附加包

上面说了,本地通知的附加包数据是放在本地的,直接根据其文件的URL地址创建即可,下面给出一个示例:

        // 创建通知内容let content = UNMutableNotificationContent()content.title = "ios 10 local push test"content.subtitle = "local push subtitle"content.body = "这是一个iOS 10 之后的本地通知测试文本,这里显示的是消息的详细内容,另外这是一个添加的附件图片的通知"content.sound = .defaultcontent.userInfo = ["info": "这里的信息是传递给app的payload内容"]// 加载本地的一张图片作为附件if let url = Bundle.main.url(forResource: "111", withExtension: "png") {if let attch = try? UNNotificationAttachment(identifier: "identifierAttachment", url: url, options: nil) {content.attachments = [attch]}}// 创建触发方式,10s后触发let timer = UNTimeIntervalNotificationTrigger(timeInterval: 10, repeats: false)// 创建通知请求let req = UNNotificationRequest(identifier: "reqid", content: content, trigger: timer)// 添加请求到通知中心UNUserNotificationCenter.current().add(req) { (error) inprint(error)print("prepare for local push")}

通知执行后,在锁屏状态通知中心显示为:

弹框的显示效果

弹框下拉后会显示一个大图

也可以加载一段音乐,例如加载一首歌,只需要把上面的加载附件的部分代码修改为:

// 加载本地的一张图片作为附件if let url = Bundle.main.url(forResource: "music", withExtension: "mp3") {if let attch = try? UNNotificationAttachment(identifier: "identifierAttachment", url: url, options: nil) {content.attachments = [attch]}}

弹框下拉后如下图效果:

可以看到,这里可以直接播放,视频的加载方式类似,只要不超过大小限制即可!

远程通知携带附加包

远程通知的附件数据是存放在服务端的,所以我们发送的Payload需要添加mutable-content字段,并设置其值为1 ,告诉系统此通知是可变的,然后再通过Service Extensions服务来下载对应的数据创建attachments,添加到相应的通知里面,显示在通知里。
Payload 模板:

{"aps":{"alert":{"title":"iOS10远程推送标题","subtitle" : "iOS10 远程推送副标题","body":"这是在iOS10以上版本的推送内容,并且携带来一个图片附件"},"badge":1,"mutable-content":1,"sound":"default","image":"http://pic29.nipic.com/20130511/9252150_174018365301_2.jpg"}
}

添加 Service Extension 服务

首先,添加一个扩展服务Target
选择:导航栏 File -> New -> Target

在弹出的页面中选择Notification Service Extension,下一步,起一个名称,完成即可!可以看到,项目中多了一个Target,以及几个相关的文件:

我需要在生成的NotificationService文件里处理我们发送的通知,添加相应的附件,可以看到NotificationService是继承自UNNotificationContentExtension的,并重写了他的两个方法,定义了两个属性:

import UserNotificationsclass NotificationService: UNNotificationServiceExtension {var contentHandler: ((UNNotificationContent) -> Void)?var bestAttemptContent: UNMutableNotificationContent?override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {self.contentHandler = contentHandlerbestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)if let bestAttemptContent = bestAttemptContent {// Modify the notification content here...bestAttemptContent.title = "\(bestAttemptContent.title) [modified]"contentHandler(bestAttemptContent)}}override func serviceExtensionTimeWillExpire() {// Called just before the extension will be terminated by the system.// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {contentHandler(bestAttemptContent)}}

如果我们什么都不更改,使用上面的Payload模版发送一个远程通知试试,会发现我们设置的标题后面多了个**[modified]**,这是因为修改了标题。可见,通知调用了这个方法,但是,当我们在这个文件内添加打印log的print,或者断点,log信息并没有输出,断点也没有停,虽然这个方法确实是被系统调用了,这给我们的调试带来了一些不方便。

我们主要是在didReceive方法里添加相应的处理:下载附件的数据,保存到本地,然后根据本地的文件URL创建UNNotificationAttachment实例对象,添加到通知里,并回调给系统。

以携带一张图为例:

if let bestAttemptContent = bestAttemptContent {// Modify the notification content here...bestAttemptContent.title = "\(bestAttemptContent.title) [modified]"print(bestAttemptContent.userInfo)// 1. 获取payload内容// 此处的 userInfo 即我们发送的Payload内容if let aps = bestAttemptContent.userInfo["aps"] as? [String: Any] {// 2. 获取到payload内的图片地址if let imagePath = aps["image"] as? String {//                    bestAttemptContent.body = "\(bestAttemptContent.body) +imagePath \(imagePath)"if let url = URL(string: imagePath) {//                        bestAttemptContent.body = "\(bestAttemptContent.body) +url \(url)"// 3. 根据URL地址获取图片数据if let data = try? Data.init(contentsOf: url) {let path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true).first// 4. 创建本地文件地址,最好在payload中添加一个文件名称,或者文件格式,在这里使用文件原名称/格式进行存储;这里直接写死let fileUrl = URL.init(fileURLWithPath: path! + "/image.jpg")//                            bestAttemptContent.body = "\(bestAttemptContent.body) +file \(fileUrl)"// 5. 保存图片数据到本地try? data.write(to: fileUrl)// 6. 根据本地URL地址创建UNNotificationAttachmentif let att = try? UNNotificationAttachment(identifier: "imageattac", url: fileUrl, options: nil) {bestAttemptContent.attachments = [att]}} /* if let data = end*/} /* if let url = end*/}/* if ler imagePath = end*/}/* if let aps = end*/// 7. 回调contentHandler(bestAttemptContent)}

实例代码中的1.–7.是相关需要操作的步骤,还有注释掉的bestAttemptContent.body = 部分代码,因为无法打印log,为了能看到相关的信息,我就把这些信息添加到body里面,然后显示在通知里了。

这时,再去发送一个通知:
在锁屏页面,或者弹框,是这样的

点击查看,或者下拉弹框,会显示大图

如果是其他的文件,例如视频、音频文件,都可以按此步骤来操作,下载的方式可以使用自己项目中使用的网络框架进行。需要注意的是,此处下载的时间只有30s,所以附件一定要控制大小,如果在此时间内没有下载完成,或者下载失败,将会以原通知的内容进行推送,不含有附件。

PS: 这里需要注意,使用到这个功能的时候,一定要有访问网络的权限,也就是要在弹出那个网络权限的选择框之后。我在写demo的时候,因为没有用到网络,在此之前没有申请网络的授权访问,所以一直没有出现图片!

[iOS] 通知详解: iOS 10 UserNotifications -- 附加包Media Attachments相关推荐

  1. iOS无处不在详解iOS集成第三方登录(SSO授权登录无需密码)

    链接地址:http://www.it165.net/pro/html/201408/18884.html 1.前言 不多说,第三登录无处不在!必备技能,今天以新浪微博为例. 这是上次写的iOS第三方社 ...

  2. iOS教程:详解iOS多图下载的缓存机制

    ios教程,ios的干货一直来不及给大家分享,小编也是一直在忙啊!今天给大家献上ios:详解iOS多图下载的缓存机制 1. 需求点是什么? 这里所说的多图下载,就是要在tableview的每一个cel ...

  3. “iOS 推送通知”详解:从创建到设置到运行

    "iOS 推送通知"详解:从创建到设置到运行 转自 http://www.csdn.net/article/2012-02-18/311976 这是一篇编译的文章,内容均出自Par ...

  4. IOS UIView详解

    文章目录 IOS UIView详解 1.官方类分析 2. UIView 常用的属性 2.1 UIView的圆角加阴影效果的实现 2.2 UIView 属性 2.2.1 UIView 几何属性 2.2. ...

  5. iOS多线程详解:实践篇

    iOS多线程实践中,常用的就是子线程执行耗时操作,然后回到主线程刷新UI.在iOS中每个进程启动后都会建立一个主线程(UI线程),这个线程是其他线程的父线程.由于在iOS中除了主线程,其他子线程是独立 ...

  6. iOS绘图详解-多种绘图方式、裁剪、滤镜、移动、CTM

    iOS绘图详解 摘要: Core Graphics Framework是一套基于C的API框架,使用了Quartz作为绘图引擎.它提供了低级别.轻量级.高保真度的2D渲染.该框架可以用于基于路径的 绘 ...

  7. iOS疯狂详解之开源库

    youtube下载神器:https://github.com/rg3/youtube-dl vim插件:https://github.com/Valloric/YouCompleteMe vim插件配 ...

  8. php图片涂鸦,IOS_详解iOS App中图片的线段涂鸦功能的添加方法,接下来我们要讲图片的涂鸦, - phpStudy...

    详解iOS App中图片的线段涂鸦功能的添加方法 接下来我们要讲图片的涂鸦,我们分开一点一点拓展,先给图片上划线 创建项目 起名testAddLine 接下来我们在默认生成的ViewControlle ...

  9. 深拷贝与浅拷贝(mutableCopy与Copy)详解 iOS

    深拷贝与浅拷贝(mutableCopy与Copy)详解 iOS ios中并不是所有的对象都支持copy,mutableCopy,遵守NSCopying 协议的类可以发送copy消息,遵守NSMutab ...

  10. FreeEIM 来点新知识iOS UIScrollView详解

     老程序员FreeEIM 来点新知识iOS UIScrollView详解 UIScrollView 顾名思义也知道这个是和滚动相关的控件,在Android开发时遇到过ScrollView,当内容的 ...

最新文章

  1. linux中看挂载的磁盘用什么命令,使用Linux命令行挂载硬盘和分区 | MOS86
  2. PHPExcel常用方法汇总
  3. PHP如何用mvc,在PHP中使用MVC模式进行开发
  4. 在O(1)的时间内计算n个整数落在区间[a,b]的个数(预处理时间为O(n+k))
  5. 四张图带你了解Tomcat系统架构--让面试官颤抖的Tomcat回答系列
  6. Python 多进程
  7. L3-028 森森旅游 (30 分)-PAT 团体程序设计天梯赛 GPLT
  8. SparkContext详述
  9. win10+Linux双系统安装
  10. 记工软件 包工头记工软件 建筑记工软件 工程记工软件
  11. GBASE监控工具简介
  12. 一 集成电路与IP核技术
  13. HTML生日快乐-生日祝福(烟花+粒子动画)
  14. 发挥数字化平台优势,电子元器件采购商城系统助力企业改变固有低效流程
  15. Python实现烟花效果,祝大家2021年,牛年大吉。
  16. 双屏显示html vga,双屏显示设置【具体方法】
  17. 计算机上的查找替换功能快速格式化,Excel 2016中使用查找替换功能应用技巧
  18. 1588的E2E链路延迟测量机制
  19. IDEA最好用的插件
  20. java毕业设计基于的电商平台的设计与实现Mybatis+系统+数据库+调试部署

热门文章

  1. springboot集成quartz完成定时任务
  2. Android Studio向SVN上传新项目
  3. 如何查看CentOS操作系统版本
  4. Java项目文件目录结构介绍
  5. Ubuntu18.04完全美化及常用软件安装 |QQ|TIM|微信|坚果云|备份
  6. 计算机软考初级信息技术试题及答案,2015年软考信息技术处理员考试模拟试题及答案...
  7. 【应急响应】Linux应急响应入侵排查思路
  8. c语言实用程序6,C语言实用程序设计100例流程图
  9. 高频面试题解析:jmeter 面试题剖析实战
  10. 吴恩达深度学习课程第四章第二周编程作业(pytorch实现)