ios - 我们如何使用 pjsip 和 callkit 处理多个调用
问题描述
我们正面临一个关于 iOS 的 callKit 框架的问题。
我们必须在应用程序中实现以下功能。
- 一对一通话(工作正常)。
- 我们可以结束并接受第二个电话(工作正常)。
- 我们可以保留和接听电话(最多 2 个电话)。
- 我们可以在通话之间切换。
- 保持/取消保持当前通话。
问题:我们面临的问题是:
我们能够在保持和接受时接受没有音频的第二个呼叫。
呼叫套件中的切换呼叫按钮已禁用。
我们已经完成了以下处理多个调用的实现:
我们正在通过以下方法报告新呼叫。
- (void)reportNewIncomingCallWithUUID:(nonnull NSUUID *)UUID handle:(nonnull NSString *)handle
completion:(nullable void (^)(NSError *_Nullable error))completion {
CXCallUpdate *update = [[CXCallUpdate alloc] init];
update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:handle];
update.hasVideo = NO;
update.supportsDTMF = YES;
update.supportsHolding = YES;
update.supportsGrouping = YES;
update.supportsUngrouping = YES;
[_provider reportNewIncomingCallWithUUID:UUID update:update completion:^(NSError * _Nullable error) {
completion(error);
if (!error) {
}
}];
}
在第二次通话时,它将询问用户(结束并接受)或(保持并接受)
当我们点击保持并接受
- (BOOL)provider:(CXProvider *)provider executeTransaction:(CXTransaction* )transaction
{
NSLog(@"executeTransaction : %@", transaction.debugDescription);
BOOL callEnd = NO;
BOOL callHold= NO;
BOOL callAnswer = NO;
NSPredicate *filter = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@", [CXEndCallAction class]];
NSArray *ends = [transaction.actions filteredArrayUsingPredicate:filter];
callEnd = [ends count] >= 1;
filter = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@", [CXAnswerCallAction class]];
NSArray *answer = [transaction.actions filteredArrayUsingPredicate:filter];
callAnswer = [answer count] >= 1;
filter = [NSPredicate predicateWithFormat:@"self isKindOfClass: %@", [CXSetHeldCallAction class]];
NSArray *hold = [transaction.actions filteredArrayUsingPredicate:filter];
callHold = [hold count] >= 1;
if(callHold && callAnswer){
pjsua_set_no_snd_dev();
Call *currentCallObject = [self getCallObjectFromUUID:callAnswer.callUUID];
if (currentCallObject != nil) {
pjsua_call_id callId;
callId = currentCallObject._call_id;
[self startAudio];
[currentCallObject answerCallWithCompletion:^(BOOL isSucceed) {
if (isSucceed) {
CallInfo *callForHold;
callForHold = [self getCallToBeHoldFromUUID:callHold.callUUID];
if (callForHold != nil) {
[callForHold holdCurrentCall];
}
}
}];
}
return YES;
}else{
return NO;
}
}
这就是我们在保持和接受时接受第二个呼叫的方式。哪个工作正常,没有为接受的呼叫激活音频。并调用了以下方法:
- (void)provider:(CXProvider *)provider didDeactivateAudioSession:(AVAudioSession *)audioSession{
现在交换呼叫的按钮被禁用了。
查询:
- 如何解决音频问题?
- 我们可以启用切换通话按钮吗?
- 如果启用了该按钮,那么在切换呼叫时将调用哪个方法?
伙计们,如果有人使用过 callKit 和 pjsip ,请帮帮我。谢谢。
解决方案
接听电话时,请完成保持操作以确保 callkit 保持当前通话。这将启用交换呼叫按钮。
不要忘记为 CXCallUpdate 启用以下内容:
update.supportsHolding = YES;
update.supportsGrouping = NO;
update.supportsUngrouping = NO;
-(void)provider:(CXProvider *)provider performSetHeldCallAction:(CXSetHeldCallAction *)action{
if (action.onHold) {
[callForHold holdCurrentCall];
}else{
[callForHold unHoldCurrentCall];
}
[action fulfill];
}
以上是hold的代码。不要忘记做[动作完成]
当您点击交换按钮时,CXHeldCall 将被触发 2 次:
- 一个呼叫被保持(从动作的 callUUID 中找到呼叫对象并保持该呼叫)
- Second Call to be Unhold(从 action 的 callUUID 中找到调用对象并取消保持该调用)
干杯;)
推荐阅读
- twitter-bootstrap-3 - 如何在引导程序的列中获取产品
- spring - Spring 5 Webflux 休息控制器 - 如何执行输入验证?
- netty - 使用 Spring WebClient 时,连接被关闭,因为 HttpClientOperations Received last HTTP packet
- java - Apache camel File i/o - 性能
- python - 终端python 2.7上同一位置的动态更新文本
- r - 将水平线添加到 xts 绘图
- apollo - 为什么 apollo 不为此查询调用我的 cacheRedirect?
- reactjs - Apollo React GraphQL VariableTypeMismatch 错误
- node.js - 我应该从 Express.JS 切换到 Sails.JS 吗?
- javascript - 如何使用 php 将动态创建的表单字段更改为数据库?