iOS10,对于voip 应用的app来了一个强有力的功能,系统级通话界面的支持。
参考之:【Dev Club 分享第十一期】QQ电话适配iOS10 Callkit框架分享 http://dev.qq.com/topic/58009392302e4725036142fc
上面的分享已经对CallKit的主要流程做了比较详细的说明,这边就不重复了。主要说下几点我在实际过程中遇到的比较重要的地方。
1.CXProviderConfiguration 配置项:
如果需要实现类似whatsApp 长按系统联系人中的呼叫或视频 弹出app内拨打该号码的功能。如下图所示:
那你可能需要实现它的属性supportedHandleTypes 可支持的事件类型,且这个功能只有在这个方法调用到之后,才会注册到系统,所以要注意调用这句话的时机!
typedef NS_ENUM(NSInteger, CXHandleType) {
CXHandleTypeGeneric = 1,
CXHandleTypePhoneNumber = 2,
CXHandleTypeEmailAddress = 3,
} API_AVAILABLE(ios(10.0));
maximumCallGroups 不能设置为0 否则在主动拨打时会报错errorCode 7
CXErrorCodeRequestTransactionErrorMaximumCallGroupsReached
2.CXHandle call的事件:它的value 如果是电话号码,呼入和呼出时,value最好与通讯录中的号码格式保持一致(有无+区号),简单的说就是取系统的手机号码。
CXHandle *handle = [[CXHandle alloc] initWithType:(CXHandleType)person.personHandle.type value:self.currentPhoneNumber];
3.利用CXCallObserverDelegate的返回,可以比较清楚的知道这个call的流程走向。
看一下demo中.h的方法 能知道大概的思路和使用了吧:
/*** 接收方 展示电话呼入等待接收界面 ****/
- (void)showCallInComingWithName:(NSString *)userName andPhoneNumber:(NSString *)phoneNumber isVideoCall:(BOOL)isVideo;
/**** 拨打方 呼出电话 ****/
- (void)starCallWithUserActivity:(NSUserActivity *)userActivity;
/******* Action **********/
//拨打方 开始连接
- (void)startedConnectingOutgoingCall;
//拨打方 通话连接成功 显示通话时间
- (void)connectedOutgoingCall;
//拨打方 结束通话调用
- (void)endCallAction;
//接听方 结束电话
- (void)finshCallWithReason:(CXCallEndedReason)reason;
/****** commom *****/
//禁音通话
- (void)muteCurrentCall:(BOOL)isMute;
//保留通话
- (void)heldCurrentCall:(BOOL)onHold;
//设置双音频功能
- (void)playDTMFCurrentCall:(CXPlayDTMFCallActionType)playType andDigits:(NSString *)digits;
//设置群组通话
- (void)setGroupCurrentCallWithGroupUUID:(NSUUID *)groupUUID;```
其他的就不多说了,主要查看系统api方法
因为在开发时没有找到OC的demo,下面提供自己针对上面流程写的一个简单demo //https://github.com/weskhen/CallKitManager
有不正确的地方,希望看到的大神帮忙指点下。
补充: 对锁屏下接听,不进入app里面,如何让系统界面显示为 扬声器打开状态,这个目前尝试多变,都没有找到方法。在CallKit API中没有看到对扬声器状态的控制,imo这个视频功能 没有用系统界面的,不知道是不是也没有找到这个方法,还是其他原因。如果有谁知道的麻烦指点一下,谢谢!
---------
PS: 锁屏下 点击进入app 获取扬声器状态 展示最新UI 函数方法比较简单
- (BOOL)currentOutputIsInSpeaker
{
NSArray* output = [[AVAudioSession sharedInstance] currentRoute].outputs;
if (output.count >0) {
NSString *newOutput = [[output objectAtIndex:0] portType];
if ([newOutput isEqualToString:AVAudioSessionPortBuiltInSpeaker]) {
return YES;
}
}
return NO;
}