-->

How can we handle multiple calls with pjsip and ca

2019-05-10 08:36发布

问题:

We are facing an issue regarding callKit Framework by iOS.

We have to implement following functionalities in app.

  • One to One call (Working fine).
  • we can end and accept second call (Working fine).
  • we can hold and accept calls (max 2 calls).
  • we can switch between calls.
  • Hold/Unhold current call.

Issue : The issues we are facing are :

  • We are able to accept second call which have no audio when hold and accept.

  • Switch call button from call kit is disabled.

We have done following implementation for handling multiple calls :

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{

Now the button of swapping calls are been disabled.

Queries :

  • How to resolve audio issues ?
  • Can we enable switch call button ?
  • If that button is enabled then Which method will be called while switching calls ?

Guys If anyone have worked with callKit and pjsip , Please help me out with this. Thanks.

回答1:

While accepting the call please fulfill the held action to make sure callkit hold the current call. That will enable Swap call button.

Don't forget to enable following stuffs for 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]

When you click on swap button , CXHeldCall will be triggered 2 times :

  • One call to be hold (Find the call object from callUUID of action and hold that call)
  • Second Call to be Unhold (Find the call object from callUUID of action and unhold that call)

Cheers ;)