Notification
苹果的notification包含了两个类型
Local Notification
Remote Notification
当接收到推送的时候,我们可以做出相应的提示
一个AlertView提示
一个Application icon上的badge
一个语音
我们可以将Local Notification 和 Remote Notification当成一种类型来处理,这样对于用户来说是比较容易接受的,毕竟都是推送。但是如果你想定制不同的类型,也是可以的,苹果给出了每个类型对应的API,所以对于单独的定制也是支持的。
Location Notification
这个通知一般都是由客户端主动发起,用一个定时器,定时的发出一个本地通知。所以这个通知中一般包含下面的内容
- Scheduled time.定制时间
- Notification type.通知类型(这里包含信息,按钮,事件,声音,一个数字)
- Custom data.自定义的数据
这里需要注意的就是,这个自定义的Location Notification数量有限,最多只能支持64个本地通知,循环的通知只能算一个通知。想一想还是很多的。
Remote Notification
远程推送和本地推送逻辑上都是一样的,只是一个是本地发出的通知,另一个是服务端发出的通知。所以在设计到网络服务的时候东西就会变得麻烦了很多。这里主要讲述的是苹果的APNs服务,
需要注意的点是,当设备没有连接网络的时候。后台是不会向客户端发送推送的,而这些已有的推送会在后端保存,当前端处于网络环境的时候,会向客户端发出推送。这里可能会涉及到消息过时的处理。
注册、调度和处理用户通知
Apple在ios8之后需要通过在UIApplication文件中实现 registerUserNotificationSettings:函数来告诉系统当一个新的通知来临的时候,以什么样的方式展示给用户,这里给出一个事例demo
UIUserNotificationType types = (UIUserNotificationType) (UIUserNotificationTypeBadge |
UIUserNotificationTypeSound | UIUserNotificationTypeAlert);
UIUserNotificationSettings *mySettings =
[UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
上图的demo中给出的是在通知来临的时候可以展示alert,badge,sound来提示用户。为了区分交互类型的,
在设置actionNotification是会设置一个变量
[tempCategory setActions:@[tempAction] forContext:UIUserNotificationActionContextDefault];
UIUserNotificationActionContextDefault这是一个枚举类型,通常就是default,默认情况支持4个action,另一个值的action值,只是支持2个action。这个应用场景没有做实际的检验,但是从文档中看,可以看出在不同的屏幕尺寸上展示4个action似乎回事有问题的。所以在小屏手机上还是考虑一下action的优先级,分情况去展示这个action
对于ios8之后的系统,程序需要实现以下的这几个delegate去处理自定义的action的识别
// 处理远程自定义action推送
application:handleActionWithIdentifier:forRemoteNotification:completionHandler:
// 处理本地自定义action推送
application:handleActionWithIdentifier:forLocalNotification:completionHandler:.
APNs
APNs可以说是远程推送的核心内容,它是一个健壮的高效的服务在分发消息到远程的设备上。每一台远程设备都建立一个被认证的加密的IP远程连接来接受服务端分发的消息,如果当一个远程信息到达的时候,用户由没有在使用手机,这个时候就会在用户的设备上显示一个提示,等待用户去处理相关的信息
服务端向用户提供需要push的信息,并将这些信息封装在payload&attaches,用HTTP/2的网络多路传输的方式去分发相应的push,APNs的处理是在用户端做的处理
payload
payload是每个notification都包含的模块,因为它相当于notification的信息载体,可以包含信息,alert,sound,badge或是自定义的data。但是在内容的大小是有限制的
* ios8之后使用HTTP/2传输的payload的size是4kb
* ios8之后使用二进制协议传输的payload的size是2kb
* ios8之前是256byte
自定义的json只能包含下面集中类型
* dictionary
* array
* string
* number
* bool
表现
当程序不处于foreground运行的时候,手机界面上会显示一个notification。点按这个notification,指定的程序会被启动。当程序处于运行状态时,手机不会出现notification,而是直接调用已经实现的代理。
这里需要注意的是,APNs的 Qualit of Service(Qos)执行的store-and-forward函数在处理下线设备接收推送是这样处理的
当服务器发出了一个推送给到了APNs,当时当前的设备是不在线,这时,APNs缓存当前这一条信息,当设备恢复有网状态的时候,这个时候,如果这个notification还没有过期,APNs会将这一条信息推送给前端。但是,如果这个设备一直不在网络服务的状态,且这个时候服务器又发来了多个notification,这个时候就会执行这个函数,结果就是,只保留最新的notification,将之前的的notification都置为忽略的状态。但是最后的这个最新的notification也是有时效限制的,所有,设备在一段时间不上线的话,这个notification也是会过期的
notes
设备的token是会变化的这些token的变化一般会在这样的条件下变化
- 恢复备份数据
- 更新操作系统信息
- 重置系统内容
所以注册token的方法总是在设备启动的时候执行一次,当拿到这个token及时传输到服务器,同步设备信息,才能准确及时的接收到通知。同时需要注意的是,这个代理方法的调用是随机的,只要这个设备的token变化了,这个代理方法就会被调用。所以代理方法的调用不仅仅是在程序启动注册或是重新注册的时候才会调用。所以最好不要缓存这个token。这也说明了这个Token不是唯一能标明设备的id。
ios10之前的nitification不能知道通知是否正常送达,所以在推送的信息最好不要是“敏感信息”,这个敏感信息包含的就会很多,比如说
条件性的信息
验证性的信息
在播放音乐的时候,只是支持一下几种格式
- aiff
- wav
- caf
如果格式不支持的话,可以打开相关的视屏到处对应的格式,同时在这里需要说明的是,视屏文件的大小不能超过30秒。这里还介绍了一个视屏格式转化的工具 afconvert
。
afconvert /System/Library/Sounds/Submarine.aiff ~/Desktop/sub.caf -d ima4 -f caff -v
具体的工具的使用还是去google一下,这里只是做一个介绍
远程推送,本身支持如何通知用户,例如你可以使用一个alert,或是一个声音,或是一个badge.都是可以的。但是在现在的使用场景中,大部分使用的都是自定义的payload
相关博文
WWDC2016-session707 Introduction to Notifications