PushKit的使用

作者: 子瑜愚 | 来源:发表于2016-12-03 23:23 被阅读7962次

    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解释的文章

    相关文章

      网友评论

      • humouroutlaw:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure in /Users/humoroutlaw/Downloads/VoIPPush-master/pushMe-2.php on line 23 这个怎么解决
      • LV大树:新东西,现在才知道。
      • 383dd5fb6a9b:服务器这么开发,第二个文章脚本找不到
      • 叶情宇:你好,我想问下我们知道APNS推送响铃最多也就30s的铃声限制,如果使用pushkit,收到通知时,我们可以弹出本地通知,估计这个本地通知还是有30s的铃声限制吧,是否可以初始化一个player播放一个应用的本地1分钟的音乐文件,达到长时间响铃的效果,我担心的是播放不了那么长时间吧(pushkit只用10s的执行代码时间)
        子瑜愚:@叶情宇 不好意思,你的问题我没实践过。我是通过pushkit通知来开启callkit电话响铃。callkit只在ios10以上支持,10以下系统我用的是本地通知,但是并没有播放铃声。
      • 9a6f4c00fe70:您好,想请问网路电话是当设备在后台时会先透过pushKit去唤醒app然后再启动callKti,不知道我这样的理解是否正确?
        子瑜愚:是的呀,服务端通过pushkit推过来,然后自己去启动callkit
      • 西蒙SIMON:厉害厉害
      • ShenYj:多谢分享
      • JornyQi:你好,有没有相关demo,谢谢。。

      本文标题:PushKit的使用

      本文链接:https://www.haomeiwen.com/subject/ywucmttx.html