国庆节过完了,回家好好休息一天,今天好好分享一下CallKit开发。最近发现好多吃瓜问CallKit的VoIP开发适配,对iOS10的新特性开发和适配也在上个月完成,接下来就分享一下VoIP应用如何使用CallKit后台、锁屏接听和号码识别功能。
一、首先使用CallKit能做什么:(一句话,不仅让VoIP应用具有系统电话一样的功能,还能帮助系统实现来电识别等功能;但本身并不具备voip功能)
1.后台或锁屏时直接通过系统电话界面接管VoIP语音来电,并更新回调电话操作到app(包括接听、挂断、暂停/保留、静音、DTMF信息等等);
2.电话黑名单拦截和来电识别拓展功能(这个大家在安卓XX手机管家、卫士上司空见惯了)
3.强调一下CallKit的主要功能是作为平台管理包括VoIP在内的电话,提供统一接听操作管理入口和权限。而不仅仅是有人以为的做提供来电识别拓展的!!!
二、看看CallKit的API类簇功能吧:
1、CXCall:电话信息基类,有一个唯一识别符UUID,是系统用以区分一个唯一来电信息的东西、通过这个ID可以地位到特定时刻的特定号码的来电信息。
2、CXCallUpdate:通话过程就是信息和状态的变化过程,CallKit的作用只是在于将通话状态和信息在系统接听界面和应用之间传递 ,通过provider请求进行处理;
3、CXAction/CXCallAction:电话操作载体类,细分包括(电话开始:CXStartCallAction、 接听:CXAnswerCallAction、暂停:CXSetHeldCallAction、静音:CXSetMutedCallAction、群组电话CXSetGroupCallAction、双频多音功能:CXPlayDTMFCallAction、挂断或拒接:CXEndCallAction )。
4、CXTransaction:操作执行类;CXCallController:话务控制器,每种action在配置好CXTransaction后都需要控制器CXCallController去向系统发起请求来响应操作:
- (void)requestTransaction:(CXTransaction *)transaction completion:(void (^)(NSError *_Nullable error))completion;
5、CXProvider/CXProviderDelegate:使用CallKit代接收来电状态的VoIP应用都需要一个初始化一个CXProvider,比如有来电时通过provider告知系统帮我接听、要呼出电话时告知系统这条电话的基本信息、以及各种操作和状态的更新信息会通过协议代理传回应用;并需要设置一个代理类来接受处理CXProviderDelegate 代理任务操作(各种CXAction:接听、挂断、DTMF、免提等本地操作)。使用之前,通过 CXProviderConfiguration来配置app的具体信息(你的VoIP 自己的显示名称、是否要支持视频通话、最大会话分组数、logo、来电提示音等信息),以便在系统通话界面显示。
6、CXCallObserver可以设置一个代理来随时捕获电话信息的更新;
7、******接下来是app extension相关的API类:CXCallDirectory电话的地址,目前只有号码CXCallDirectoryPhoneNumber;CXCallDirectoryExtensionContext:拓展应用中用来接受黑名单号码信息和号码识别信息数据源的类;
三、如何使用和需要哪些:
1、初始化一个CXProvider、CXCallController,看看API,配置好代理,准备接受CXCallUpdate;每一种CXCallAction对应一个CXTransaction去执行,因为他有一个管理队列/// Add the provided action to the receiver's list of actions
- (void)addAction:(CXAction *)action;
//无论何种操作都需要 话务控制器 去 提交请求 给系统
-(void)requestTransaction:(CXTransaction *)transaction completion:(XWCallKitCenterCompletion)completion
-(void)requestTransaction:(CXTransaction *)transaction{
[_callController requestTransaction:transaction completion:^( NSError *_Nullable error){
if (error !=nil) {
NSLog(@"Error requesting transaction: %@", error);
}else{
NSLog(@"Requested transaction successfully");
}
}];
}
2、在后台或者锁屏时,请求系统代为接听来电(这才是CallKit的主要功能):
[provider reportNewIncomingCallWithUUID:uuid update:update completion:^(NSError * _Nullable error) {
if (error == nil) {
XWCall *call = [[XWCall alloc] initWithUUID:uuid];
call.handle = handle;
[[XWCallManager sharedManager] addCall:call];
}
completion(error);
}];
3、使用Siri识别来拨打电话、在系统听话记录里回拨等UserActivity回调到你的VoIP网络电话app里,app如何接受这个UserActivity,并发起点VoIP电话请求:详见demo
4、至于做这个号码识别和黑名单拦截就更简单了,你在工程中添加CallDiretoryExtension拓展的时候,它就帮你写好代码了,看懂了自定义数据源就可以了。不过这个功能多数情况没效果,大概是系统权限或者bug吧。
5、另外iOS10已经警告VoIP功能的应用去使用PushKit来接受来电推送,以往的VoIP后台申请不受支持。具体代码很简单,跟remote notification差不多:PKPushRegistry看看API就知道怎么耍了。
******分享这些一来来是回答网友的问询,二来自己总结一下思路清晰点;不喜欢发代码和Demo ,授之以鱼不如授之以渔,自己看懂了自己写个demo跑一下比看别人写的再规范的demo都好,但是如果还是有需要下次再发简版demo。再次强调,callKit但本身并不具备voip功能,不要以为单纯接入CallKit就可以真正童话了,自己本身要具备语音通话功能。
潜水了几年,最近觉得朋友和boss说多敲也要多分享总结交流,也许有道理吧,以后有空就吓写写吧!随手写的,欢迎指正,对voip感兴趣的欢迎交流。本人自己制作的voip语音视频通话SDK,需要的联系我:微博:_viviwu_;
既然有不少人没搞懂,还是发个简单的CallKit demo吧,star一下手留余香!用objective-C 写的一个简版CallKit Demo,展示iOS10 CallKit的使用介绍 CallKit的基本使用。