iOS CallKit框架 详解(此一篇足矣)

 

CallKit 是一个iOS10新框架,用于改善 VoIP 的体验,允许 App 和原生的 Phone UI 紧密集成,你的 App 将能够:

  • 调用原生的呼入界面,无论锁屏/不锁屏状态。
  • 从原生电话 App 的通讯录、个人收藏、最近通话中发起通话。
  • 通过系统服务监听来电和去电。
  • 用电话通讯录识别或拦截来电。

CallKit 通话流程如下图:

iOS CallKit框架 详解(此一篇足矣)_第1张图片

 

---------------- 用户行为传递给系统 --------------- 

CXCallController类 :程序向系统传递信息

- (instancetype)init; //在私有串行队列创建.
- (instancetype)initWithQueue:(dispatch_queue_t)queue;   //指定队列里创建.默认主线程 //指定使用


@property (nonatomic, readonly, strong) CXCallObserver *callObserver;    //电话信息观察者
{
CXCallObserver类  :随时捕获电话信息的更新
一个方法:- (void)setDelegate:(nullable id)delegate queue:(nullable dispatch_queue_t)queue;
一个代理:- (void)callObserver:(CXCallObserver *)callObserver callChanged:(CXCall *)call;
一个属性:@property (nonatomic, readonly, copy) NSArray *calls;//返回当前呼叫列表


CXCall类 :电话信息类

UUID  //唯一通过这个ID可以定位到特定时刻的特定号码的来电信息

outgoing    // (bool)是否是自己拨打的

onHold   //电话是否挂起

hasConnected    //电话是否接通

hasEnded    //电话是否结束
}


//以下三个方法:将CXTransaction传递给系统,如果error为空,将调起CXProvider类的-provider:executeTransaction: 代理方法
- (void)requestTransaction:(CXTransaction *)transaction completion:(void (^)(NSError *_Nullable error))completion;
- (void)requestTransactionWithActions:(NSArray *)actions completion:(void (^)(NSError *_Nullable error))completion API_AVAILABLE(ios(11.0));
- (void)requestTransactionWithAction:(CXAction *)action completion:(void (^)(NSError *_Nullable error))completion API_AVAILABLE(ios(11.0));

CXTransaction类 :用户的任何操作(CXAction)被包装成CXTransaction,然后丢给CXCallController通知系统
@property (nonatomic, readonly, copy) NSUUID *UUID;     //获取唯一标识
@property (nonatomic, readonly, assign, getter=isComplete) BOOL complete;  //所有的CXAction是否已经完成
@property (nonatomic, readonly, copy) NSArray<__kindof CXAction *> *actions;   //获取CXAction列表

- (instancetype)initWithActions:(NSArray *)actions;    //初始化CXTransaction  // 指定使用
- (instancetype)initWithAction:(CXAction *)action;
- (void)addAction:(CXAction *)action;  //添加CXTransaction


CXAction类:电话操作载体类

@property (nonatomic, readonly, copy) NSUUID *UUID;  // 唯一标示

@property (nonatomic, readonly, assign, getter=isComplete) BOOL complete;  // 不论失败成功 是否完成

@property (nonatomic, readonly, strong) NSDate *timeoutDate;  // action未完成的超时时间

- (instancetype)init;  //指定初始化方法

- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder; // 指定初始化方法

- (void)fulfill; // action已经完成(在当前时间)

- (void)fail;

CXCallAction类 :CXAction的子类,以下类的父类

  • CXStartCallAction类 :电话开始 

- (instancetype)initWithCallUUID:(NSUUID *)callUUID handle:(CXHandle *)handle;

- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder;

- (instancetype)initWithCallUUID:(NSUUID *)callUUID; // 不可用

@property (nonatomic, copy, nullable) NSString *contactIdentifier;  // 呼叫接收方的标识符

@property (nonatomic, getter=isVideo) BOOL video; // 是否是视频电话

- (void)fulfillWithDateStarted:(NSDate *)dateStarted; // 指明电话的开始时间

@property (nonatomic, copy) CXHandle *handle;

{

                 CXHandle类

              @property (nonatomic, readonly) CXHandleType type;

              @property (nonatomic, readonly, copy) NSString *value;

             - (instancetype)initWithType:(CXHandleType)type value:(NSString *)value NS_DESIGNATED_INITIALIZER;

             - (instancetype)init NS_UNAVAILABLE;

             - (BOOL)isEqualToHandle:(CXHandle *)handle

  }

  • CXAnswerCallAction类 :接听

- (void)fulfillWithDateConnected:(NSDate *)dateConnected;  // 指明一个时间表明电话已经接通 

  • CXSetHeldCallAction类 :暂停

- (instancetype)initWithCallUUID:(NSUUID *)callUUID onHold:(BOOL)onHold; // 指定

- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder; // 指定

- (instancetype)initWithCallUUID:(NSUUID *)callUUID; // 不可用

@property (nonatomic, getter=isOnHold) BOOL onHold; //是否被hold

  • CXSetMutedCallAction类 :静音

- (instancetype)initWithCallUUID:(NSUUID *)callUUID muted:(BOOL)muted;

- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder;

- (instancetype)initWithCallUUID:(NSUUID *)callUUID; // 不可用

@property (nonatomic, getter=isMuted) BOOL muted;

  • CXSetGroupCallAction类 :群组电话

- (instancetype)initWithCallUUID:(NSUUID *)callUUID callUUIDToGroupWith:(nullable NSUUID *)callUUIDToGroupWith;

- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder;

- (instancetype)initWithCallUUID:(NSUUID *)callUUID;   // 不可用

@property (nonatomic, copy, nullable) NSUUID *callUUIDToGroupWith;

  • CXPlayDTMFCallAction类 :双频多音功能
  • CXEndCallAction类 :挂断或拒接

- (void)fulfillWithDateEnded:(NSDate *)dateEnded; // 指明一个end时间表完成



-------------------- 系统信息传递给用户 --------------------- 

 


CXProvider类
//初始化一个CXProvider,应该定义成单利
- (instancetype)initWithConfiguration:(CXProviderConfiguration *)configuration;   //指定使用
{
CXProviderConfiguration类
@property (nonatomic, readonly, copy) NSString *localizedName; //获取系统来电页面显示的app名称和系统通讯记录的信息
@property (nonatomic, strong, nullable) NSString *ringtoneSound; //来电铃声(在app的bundel中的)
@property (nonatomic, copy, nullable) NSData *iconTemplateImageData; //锁屏接听时系统界面右下角app图标,要40x40大小
@property (nonatomic) NSUInteger maximumCallGroups;    //最大通话组,默认2
@property (nonatomic) NSUInteger maximumCallsPerCallGroup;  //每个通话组的最大呼叫次数,默认 5
@property (nonatomic) BOOL includesCallsInRecents API_AVAILABLE(ios(11.0));   //每个通话结束是否显示在系统最近通话列表,默认YES
@property (nonatomic) BOOL supportsVideo;  //是否支持视频,默认NO
@property (nonatomic, copy) NSSet *supportedHandleTypes;   //CXHandleType
- (instancetype)initWithLocalizedName:(NSString *)localizedName;  //指定使用
}
//设置代理,queue一般直接指定为nil,即在main线程执行callback
- (void)setDelegate:(nullable id)delegate queue:(nullable dispatch_queue_t)queue;

 

重要流程:

1、来了VoIP电话后,让系统按照它的配置弹出一个系统来电界面。UUID:每次随机生成,其方法是:

- (void)reportNewIncomingCallWithUUID:(NSUUID *)UUID update:(CXCallUpdate *)update completion:(void (^)(NSError *_Nullable error))completion;

{
CXCallUpdate类
@property (nonatomic, copy, nullable) CXHandle *remoteHandle;   //通话对方的Handel信息
@property (nonatomic, copy, nullable) NSString *localizedCallerName;   //对方的名字,可以设置为app注册的昵称
@property (nonatomic) BOOL supportsHolding;   //通话过程中再来电,是否支持保留并接听
@property (nonatomic) BOOL supportsGrouping;   //通话是否可以加入一个群组
@property (nonatomic) BOOL supportsUngrouping;  //通话当被加入群组时,是否可退出
@property (nonatomic) BOOL supportsDTMF;  //是否支持键盘拨号
@property (nonatomic) BOOL hasVideo;   //本次通话是否有视频
}


2、报告系统一个通话更新。动态更改provider的配置信息CXCallUpdate,比如拨打方,开始没有配置通话的界面,就可以在通话开始时更新这些配置信息

- (void)reportCallWithUUID:(NSUUID *)UUID updated:(CXCallUpdate *)update;

3、外拨电话时
//通话连接时
- (void)reportOutgoingCallWithUUID:(NSUUID *)UUID startedConnectingAtDate:(nullable NSDate *)dateStartedConnecting;
//通话连接上
- (void)reportOutgoingCallWithUUID:(NSUUID *)UUID connectedAtDate:(nullable NSDate *)dateConnected;

4、报告系统通话结束的时间和原因
- (void)reportCallWithUUID:(NSUUID *)UUID endedAtDate:(nullable NSDate *)dateEnded reason:(CXCallEndedReason)endedReason;


@property (nonatomic, readwrite, copy) CXProviderConfiguration *configuration; //配置

- (void)invalidate;   //让provider停止(所有存在的通话都被标记为失败结束)

@property (nonatomic, readonly, copy) NSArray *pendingTransactions;  //未完成的CXTransaction列表

- (NSArray<__kindof CXCallAction *> *)pendingCallActionsOfClass:(Class)callActionClass withCallUUID:(NSUUID *)callUUID;

--------- 代理 ---------
//必须通过清除所有内部呼叫状态(断开通信信道、释放网络资源等)来响应此回调
- (void)providerDidReset:(CXProvider *)provider;

@optional
//provider创建好以后触发
- (void)providerDidBegin:(CXProvider *)provider;


//是否执行一个transaction
- (BOOL)provider:(CXProvider *)provider executeTransaction:(CXTransaction *)transaction;

// 如果 provider:executeTransaction:error: 返回 NO, 下面的方法按逻辑执行
//拨打方成功发起一个通话后触发
- (void)provider:(CXProvider *)provider performStartCallAction:(CXStartCallAction *)action;
//接听方成功接听一个电话时触发
- (void)provider:(CXProvider *)provider performAnswerCallAction:(CXAnswerCallAction *)action;
//接听方拒接电话或者双方结束通话时触发
- (void)provider:(CXProvider *)provider performEndCallAction:(CXEndCallAction *)action;
//当点击系统通话界面的 暂停 按钮时,会触发
- (void)provider:(CXProvider *)provider performSetHeldCallAction:(CXSetHeldCallAction *)action;
//当点击系统通话界面的 静音 按钮时,会触发
- (void)provider:(CXProvider *)provider performSetMutedCallAction:(CXSetMutedCallAction *)action;
//当点击系统通话界面的 添加通话 按钮时,会触发
- (void)provider:(CXProvider *)provider performSetGroupCallAction:(CXSetGroupCallAction *)action;
//
- (void)provider:(CXProvider *)provider performPlayDTMFCallAction:(CXPlayDTMFCallAction *)action;
//通话响应超时,强制通话结束
- (void)provider:(CXProvider *)provider timedOutPerformingAction:(CXAction *)action;
//audio session activation state改变时发起
- (void)provider:(CXProvider *)provider didActivateAudioSession:(AVAudioSession *)audioSession;
- (void)provider:(CXProvider *)provider didDeactivateAudioSession:(AVAudioSession *)audioSession;


------------------- app extension 相关 -------------------


CXCallDirectoryManager类
//获取app extension的授权
identifier:app extension的bundleID
enabledStatus:授权状态:未授权-授权-不知道
- (void)getEnabledStatusForExtensionWithIdentifier:(NSString *)identifier completionHandler:(void (^)(CXCallDirectoryEnabledStatus enabledStatus, NSError *_Nullable error))completion;
//需要实时更新 
- (void)reloadExtensionWithIdentifier:(NSString *)identifier completionHandler:(nullable void (^)(NSError *_Nullable error))completion;

CXCallDirectory类  
一个属性:CXCallDirectoryPhoneNumber //可以标识一个电话号码数组

CXCallDirectoryExtensionContext类
两个功能:
1>将号码添加(移除)到黑名单
2>给一个号码添加(移除)一个标识。例如腾讯手机管家中的“腾讯手机管家:骚扰电话”
一个代理:添加黑名单或号码标识出错时发起
- (void)requestFailedForExtensionContext:(CXCallDirectoryExtensionContext *)extensionContext withError:(NSError *)error

CXCallDirectoryProvider类
一个方法:- (void)beginRequestWithExtensionContext:(CXCallDirectoryExtensionContext *)context;
它基于NSExtensionRequestHandling协议,由Extention实现


------------------ 错误信息类 ----------------------

CXError类 :错误信息类

 

 

 

参考文章:

https://www.jianshu.com/p/305bd923c1ae

https://www.cnblogs.com/viviwu/p/5942483.html

https://blog.csdn.net/kmyhy/article/details/74388913

https://blog.csdn.net/zhaochen_009/article/details/53410288?locationNum=12&fps=1

 

 

-- NORMAL --

-- NORMAL --

-- NORMAL --

你可能感兴趣的:(iOS,其他框架)