iOS推送服务的变更
1.推送条幅和功能的变化
我们首先来看看推送消息是如何在手机上显示的
iOS 8 iOS 9(1) iOS 9(2)相对于iOS8,iOS9增加了输入框按钮,也就是为UIMutableUserNotificationAction增加了behavior属性
iOS 10(1) iOS 10(2)相对于iOS 9,iOS 10增加了subTitle和附件等
2.调用函数库的变化
iOS8和iOS 9使用同一套函数方法,所有的相关类声明在UIUserNotificationSettings.h和UILocalNotification.h文件中,iOS8和iOS9唯一的区别是iOS9支持输入框按钮,也就是iOS 9的UIMutableUserNotificationAction类增加了behavior和parameters属性。在iOS10中,新增了一个框架UserNotifications,提供了一套新的解决方案,所有的操作都是通过UNUserNotificationCenter执行的。
3.注册方式的变化
在这三个大的版本中,虽然注册推送的方式在不断的变化,到iOS 10甚至换了一个框架,但是推送服务的核心理念一直没变,在这里,我们可以做一个简单的划分,把注册推送服务粗略的分为下列几步:
1.创建通知分类(notificationcategory)2.创建通知设置(notificationsetting)3.注册到app
在iOS8和iOS 9的版本中,注册推送服务 在iOS 10的版本中,注册推送服务在文章开头图片上推送条幅下面还带有按钮,那么如何给推送消息添加按钮呢,这个时候就需要用到通知分类(notification category)了。我们先看两段代码:
在iOS 8和iOS 9中创建category 在iOS 10中创建category从上面两个图可以知道,不管是在哪个版本,创建通知分类(notificationcategory)的步骤都是一样的,首先会先创建notification action,然后再添加到通知分类中。一般情况下一个通知分类中会有一到两个notification action,通过notificationaction来控制按钮的一些属性。一个通知分类最多可以有两个按钮,多余的会被忽略。
4.代理方法的变化
在用到推送服务的时候,如果不需要再推送条幅下面增加按钮,那么我们平常就只需要使用下图中的这个代理方法了
在iOS8和iOS 9中当我们点击推送的条幅(注意不是条幅下面的按钮)或者收到推送消息时app处于前台状态,就会调用上图中的回调方法图中两个分别是本地推送和远程推送的通知,本地推送可以通过nitification这个参数获取userInfo和角标数,远程推送需要通过userInfo,这个userInfo是由应用服务器的推送消息中的Payload来决定的,一些自定义数据可以在这里获取。
而当我们需要为推送消息加一些点击事件,比如直接通过点击条幅中的回复按钮来回复聊天消息,那么在点击回复按钮之后,就会执行下图中的代理方法。
iOS 8中点击条幅按钮会调用的代理方法 iOS 9中点击条幅按钮会调用的代理方法如图所示,分别是在iOS 8和iOS 9中的本地推送和远程推送的代理方法,当我们点击推送条幅中的按钮时,会调用上图中的代理方法,iOS 8和iOS 9使用的是同一套函数库,为什么我们还需要区分开来写呢。因为这个代理方法在iOS8和iOS 9中有一些区别,我们通过对比可以知道,iOS9中的方法比iOS 8多了一个参数responseInfo,那么这个参数有什么作用呢?文章开头我们说iOS9比iOS8多了一个输入框按钮,我们可以通过这个responseInfo参数获取用户在输入框中输入的字符串,通过responseInfo[UIUserNotificationActionResponseTypedTextKey]来获取。
在处理点击事件时,我们如何知道点击的按钮是哪个呢?通过对比参数identifier和定义notification action时设置的identifier,可以知道是哪个按钮。
接下来,我们看看iOS 10是如何处理这些事件的。
在iOS 10中, 一般情况下,我们只需要处理这两个代理方法就可以了。iOS 10新增的变化除了之前所说的那些以外,还有一个显著的变化,就是当推送消息到达时,即使你的app处于前台,仍然可以显示推送条幅。而在iOS 10之前,app必须是在后台状态才能显示。当然,即使是iOS 10,你需要达到这种效果,还需要一些配置,你需要实现上图中的第一个代理方法,并且调用completionHandler(),这样子就可以在前台收到推送条幅了。另外,上图中的第一个代理只有在app处于前台的时候才会调用。当app处于前台时,通过completionHandler()这个block来控制推送消息是以什么样的形式通知用户,一般情况下只需要像图中那样调用就可以了。
至于上图中的第二个代理,则是在点击条幅和条幅中的按钮时会被调用,这一点需要注意一下。同样的,我们要区分是哪个点击事件,和在iOS 8、iOS 9中一样,也是根据action的identifier,只不过iOS 10的这个属性没有通过参数直接暴露出来,它被封装在参数response中,可以通过response.actionIdentifier获取,当我们点击条幅(不是按钮)时,response.actionIdentifier返回的是com.apple.UNNotificationDefaultActionIdentifier。
5.iOS 10的UNNotificationRequest
在iOS 10中,如果想要创建一个本地推送,那就必须创建一个UNNotificationRequest对象,然后通过UNUserNotificationCenter发出。那么如何创建UNNotificationRequest呢,请看下图:
UNNotificationRequest的创建从上图可以看出,在iOS 10中,要创建一个UNNotificationRequest对象,一个UNNotificationRequest需要一个UNMutableNotificationContent对象用来定义推送内容和一个UNNotificaitonTrigger对象用来定义触发条件。
UNMutableNotificationContent对象除了定义body、title等一般的属性外,还可以添加附件对象UNNotificationAttachment,附件可以是图片、音频、视频,系统在执行request之前,会先验证这些附件是否必须满足下面的条件,如果不能满足,request不会被执行。
附件UNNotificationAttachment需要满足相应的条件至于UNNotificaitonTrigger对象,我们一般使用它的子类,它有四种子类,分别是:
UNTimeIntervalNotificationTrigger定义距离当前时间多少秒之后触发本地推送
UNCalendarIntervalNotificationTrigger定义哪个时间点触发本地推送
UNLocationIntervalNotificationTrigger定义进入或离开一个经纬度范围时触发本地推送
UNPushIntervalNotificationTrigger当推送信息来自APNs时,request的触发器是这个类型
iOS 10的本地和远程推送的代理方法都是执行的同样的回调方法,所以需要通过判断response参数的notification.request.trigger的类型是否是UNPushIntervalNotificationTrigger,来判断是否是远程推送。
6.远程推送的附件添加
本地推送添加附件非常简单,只需要给UNNotificationRequest对象的content属性添加一个UNNotificationAttachment附件对象。但是在进行远程推送时,并不需要我们来创建UNNotificationRequest对象,这个时候我们就需要借助于UNNotificationServiceExtension对象。
UNNotificationServiceExtension有两个方法,分别是:
在第一个方法中,我们可以根据request参数重新定义一个UMMutableNotificationContent对象,这样我们就能加上一个附件了。比如我们可以让推送服务器推送一个图片url过来,然后在这个方法里面下载图片,将图片作为附件加入到UMMutableNotificationContent对象中,最后调用contentHandler这个block提交修改的内容。
执行第一个方法时,会有一定的时间限制,如果没有及时执行完方法,系统会在时间到期之前调用第二个方法,给你最后一次提交修改的机会。如果时间到期了,你还是没有提交你修改的内容(就是没有执行contentHandler这个block),系统会使用原来的那个内容。
使用这个UNNotificationServiceExtension对象时,我们不能直接使用它,需要自己创建一个它的子类,并重写它的这两个方法。具体如何创建以及使用可以参考http://www.jianshu.com/p/f77d070a8812。
最后推荐一个,好用的服务端推送工具NWPusher https://github.com/noodlewerk/NWPusher,它是使用oc编写的,可以在mac和iphone两个端运行,如果你有兴趣的话,建议读一读源码,可以帮助你了解整个推送服务的运行机制
参考链接:
http://www.jianshu.com/p/ff14939b6639