带CallKit的系统调用屏幕
集成Amazon SNS和CallKit
苹果宣布在WWDC16上开放API,以将iOS上的本机呼叫屏幕与VoIP(IP语音)应用程序配合使用。 我们曾经发送推播通知来通知用户电话。 在iOS10中,第三方应用程序还可以使用CallKit
通过本机呼叫屏幕通知用户。
我将总结我对CallKit
经验。
抽象
- 设置Amazon SNS
- 使用
PKPushRegistry
在应用程序上进行初始设置以接收VoIP推送通知。 - 从Amazon SNS发送VoIP推送通知
- 使用CallKit显示系统调用屏幕
从Amazon SNS接收VoIP推送通知
设置Amazon SNS
应用程序必须在后台才能显示系统调用屏幕。 VoIP推送通知使我们可以唤醒后台应用程序。
当收到VoIP推送通知时,确保应用程序在后台运行。 这使我们可以启动VoIP呼叫。 我没有注意到与常规推送通知和本地通知有这种区别,最终花费了大量时间。
但是,由于在我从事此工作的那一刻(2016年8月),Parse和Firebase不支持VoIP推送通知,因此我决定使用亚马逊的推送通知服务SNS。
在SNS上设置VoIP推送通知的过程与常规推送通知的过程几乎相同。
首先要做的是设置证书。 您可以像常规推送通知一样,从Apple Developer网站创建VoIP推送证书。 选择“ VoIP服务证书”,下载证书,然后导出P12文件。
其次,您需要在SNS上创建一个应用程序。 从AWS仪表板中选择SNS。
然后,选择应用程序>创建平台应用程序。
然后在配置中输入所需的信息。
- 应用名称:您选择的应用名称
- 推送通知平台:Apple开发或Apple生产
- 推送证书类型:VoIP推送证书
- 选择P12文件:选择使用来自Apple Developer网站的证书创建的VoIP推送通知P12文件。
- 输入密码:输入创建p12文件时指定的密码
这就是SNS设置所需的全部。 当然,您需要将此连接到服务器以进行生产。 服务器应提供一个简单的API来连接两者。
在应用程序中进行配置以接收VoIP推送通知
下一步是配置iOS项目。 选择项目文件,然后为要允许其推送通知的目标启用“功能中的后台”。 选择“ IP语音和后台提取”,以便您可以接收VoIP推送通知并在后台处理必要的步骤。
现在,我们将使用PKPushRegistry
获得设备令牌。 如下所示,我们将PKPushTypeVoIP设置为PKPushRegistry
实例。 您指定为代理的实例将接收与VoIP推送通知相关的回调。
在设备令牌注册视图中,您还可以添加用户数据。 您可以添加用户ID等以支持向特定设备发送推送通知。
让我们向设备发送VoIP推送通知。 选择您要发送通知的设备。 单击“ Push to Endpoint”将使您触发推送通知。 如果您已经完成了在客户端上的设置,则可以看到通知收据的日志。
使用CallKit显示系统调用屏幕
现在您可以发送VoIP推送通知,剩下的唯一要显示的是显示系统调用屏幕。
您将使用的课程如下。
- CXProvider:该类要求系统显示调用屏幕。
- CXProviderConfiguration:应用程序调用屏幕的配置。
- CXCallUpdate:呼叫的配置
我创建了JSKSystemCallProvider
类来添加与呼叫相关的功能。
我用をCXProviderConfiguration
初始化CXProviderConfiguration
。 您可以使用CXProviderConfiguration
配置铃声,应用程序显示名称,应用程序图标等。
开始通话
要开始通话,请致电- (void)reportNewIncomingCallWithUUID:(NSUUID *)UUID update:(CXCallUpdate *)update completion:(void (^)(NSError *_Nullable error))completion;
在CXProvider
。
当用户点击开始调用按钮时,将调用完成处理程序success()
。
与呼叫相关的信息将传递到CXCallUpdate
实例。 您可以将其设置为允许此类的视频通话和群组通话等。
https://gist.github.com/jeffsuke/3c26909853906ee6a4a758ea5e6d18b6
完成通话
由于您可以在开始通话后打开应用程序,因此我们需要考虑用户从应用程序和系统调用屏幕完成通话的两种情况。
您可以通过调用- (void)reportCallWithUUID:(NSUUID *)UUID endedAtDate:(nullable NSDate *)dateEnded reason:(CXCallEndedReason)endedReason;
完成系统调用- (void)reportCallWithUUID:(NSUUID *)UUID endedAtDate:(nullable NSDate *)dateEnded reason:(CXCallEndedReason)endedReason;
在CXProvider
。 您需要在应用程序中完成WebRTC调用后调用此方法,以确保系统调用屏幕不会以怪异的状态结束。
如果用户在系统调用屏幕上完成呼叫,则将调用以下委托方法。
调用委托方法时,调用状态为“结束通话”。 您可以通过调用[action fulfill];
将呼叫屏幕更新为“已结束呼叫” [action fulfill];
。
系统调用屏幕的陷阱
行为因设备是否被锁定而有所不同
尽管点击“开始呼叫”按钮将打开具有未锁定设备的应用程序,但将提供系统调用屏幕,并且该应用程序将在锁定设备的情况下开始在后台运行。 在这种情况下,该应用程序将在后台启动WebRTC调用。 由于我们无法在应用程序外部提供警报视图,因此如果在锁定设备的情况下开始通话,我们将无法授予麦克风和摄像头权限。 为避免用户听见但电话上的其他人听不到的情况,您需要在打开应用程序的同时开始通话之前授予许可。 我在测试功能时遇到了Skype的错误。
VoIP推送通知的生命周期
一个应用程序在收到VoIP推送通知时将在后台启动该过程,并将调用以下方法。
然后,
将被称为。 如果您在应用程序启动时有异步任务需要在调用之前完成,则可能需要等待。
我写了我在Amazon SNS上处理VoIP推送通知以及使用CallKit实现系统调用屏幕的经验。 通过接收VoIP推送通知并显示系统调用屏幕,可以为用户提供一致的体验。
苹果提供的示例项目非常有帮助。
参考文献
- 使用CallKit增强VoIP应用程序
- 音箱:使用CallKit创建VoIP应用
- 关于标准推送通知和VoIP推送通知(PushKit)之间的区别
- 应用程序的生命周期-当应用程序终止且推送工具包有效负载到来时