我们如何使用 pjsip 和 callkit 处理多个调用

How can we handle multiple calls with pjsip and callkit

iOS。

我们遇到了有关 callKit 框架的问题

我们必须在应用程序中实现以下功能。

问题:我们面临的问题是:

我们已经完成了以下处理多个调用的实现:

We are reporting new call by following method.

- (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) {
    }
}];     
}

On second call It will ask user for (End & Accept) OR (Hold & Accept)

this is how we are getting second call view

When we click on hold and accept

    - (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;
    }
}

This is how we are accepting second call while hold and accept. Which is working fine with no audio activated for accepted call. and following method is been called :

- (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];
        }

Above is the code for hold. don't forget to do [action fulfill]

当您点击交换按钮时,CXHeldCall 将被触发 2 次:

  • 一个呼叫要保持(从action的callUUID中找到呼叫对象并保持该呼叫)
  • 要取消保持的第二次调用(从操作的 callUUID 中找到调用对象并取消保持该调用)

Cheers ;)