PushKit的使用

1、为什么使用PushKit?

iOS10之后,苹果推出了CallKit框架增强VoIP应用的体验,主要表现在3个方面:

  • 在锁屏状态下,如果有网络电话呼入,VoIP应用可以打开系统电话应用的待接听界面,告别了原来推送通知的展现方式。
  • VoIP应用内发起通话、挂断电话等记录可以体现在系统电话应用的通话记录中。
  • 从系统电话应用的通话记录、通讯录或者siri进入VoIP应用,发起通话。
    总而言之,我们的VoIP应用拥有了和系统通话应用一样的用户体验

那么,如何在锁屏状态下,呼出系统应用的待接听界面?如何在app杀死或者后台的情况下,知道有用户呼入?

在iOS8之后,苹果引入新的框架PushKit,一种新的push方式,有别于普通的APNs,它不会弹出通知,而是悄悄的告诉我们的app有推送过来,让app做出相应的处理。iOS10开始,苹果不在支持VoIP应用的后台socket长连接,需要使用苹果推荐的pushkit,降低app耗电。PushKit可以说是“准实时”的,实际上延迟在1s左右。

2、PushKit的使用

2.1、制作VoIP证书

文末的参考文章1都有介绍,这里不再赘述,与APNS类似。概述一下:VoIP证书的制作入口在certificates。该证书只有生产环境下的,但是开发环境下也可使用。App ID不能使用通配ID必须使用指定APP ID并且生成配置文件中选择Push Notifications服务。

2.2、制作php服务端使用的pem文件

VoIP证书安装完成后,在keychain中将证书和证书密钥分别导出.p12格式。具体制作过程见参考文章1或者stackoverflow

2.3、客户端代码接入

  • 在目标target的capabilities->background Modes下打开“Voice over IP”
  • 引入PushKit框架
  • 在app启动后注册PushKit服务,记得做iOS8之前的版本保护
PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:nil]; 
pushRegistry.delegate = self;
pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
  • 在对应的类实现PushKit的代理方法
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type {
    NSString * tokenString = [[[[credentials.token description] stringByReplacingOccurrencesOfString: @"<" withString: @""] stringByReplacingOccurrencesOfString: @">" withString: @""] stringByReplacingOccurrencesOfString: @" " withString: @“"];
 }

设备从苹果服务器获取到了VoIP token,这个token与APNs是不一样的。app将收到的token传递给push服务器。(流程和APNs类似,但是接受的代理方法和token都是不一样的)
获取到的token也是64位的,与APNs一样,需要去掉<>和空格。

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
  // 呼出系统接听界面
  // 或者生成本地推送
 }

参数payload是一个字典,内容自定义。
上面这个回调,在一切正常的情况下, 在手机重启、应用被系统回收、手动kill程序的情况下, 依然能够被触发, 且可以有一段时间(大概10秒左右, 可能有时会比10秒少一点)用来执行自己的代码。

2.4、php服务端推送测试

php的测试代码见参考文章2,这里记录一下几个点:

  • deviceToken:开发环境和生产环境的token不一样,同一个证书可以用于开发环境也可以用于生产环境。
  • passphrase:pem文件制作时的密码,也可以不是用密码。
  • 开发环境ssl://gateway.sandbox.push.apple.com:2195,生产环境去掉其中的sandbox
  • 执行php文件的时候出现错误:error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in <Users/.../file.php> on line 30
    原因:macOS sierra 系统下php的版本引起的语法问题。
    处理方法如图:

3、其他


  1. iOS 8 pushkit使用总结(oc版本+java服务器测试)
  2. Example of iOS VoIP Notification / iOS VoIP Notification实例(swift版本+php服务器测试)
  3. 官方文档
  4. iOS 8之前socket长连接
  5. 该博主写了几篇pushkit API解释的文章
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  •   由于iOS 10禁止了VoIP类应用常驻后台的权限,导致Xcode 8 打包出来的VoIP类应用后台长连接失效...
    天明依旧阅读 3,092评论 5 4
  • 本文是翻译的 APNs 的官方说明 自己英文不是太好,花了不少时间来翻译,其实之前我是看不进去的。后来发现,只要你...
    KyleBing阅读 1,857评论 0 0
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,981评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,466评论 25 708
  • 先写一个方法按照七牛技术文档说的拼接token 加密扩展类的写法String+HMAC.swift 调用方法 完毕...
    Miu七七阅读 511评论 2 1