Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

didActivate is not called back by the CallKit

I am integrating the new CallKit API with my VOIP app.

As shown in the example app: https://developer.apple.com/library/content/samplecode/Speakerbox/Introduction/Intro.html

I am configuring the audio session:

- (void) configureAudioSession
{
    // Configure the audio session
    AVAudioSession *sessionInstance = [AVAudioSession sharedInstance];

    // we are going to play and record so we pick that category
    NSError *error = nil;
    [sessionInstance setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
    if (error) {
        NSLog(@"error setting audio category %@",error);
    }

    // set the mode to voice chat
    [sessionInstance setMode:AVAudioSessionModeVoiceChat error:&error];
    if (error) {
        NSLog(@"error setting audio mode %@",error);
    }

    NSLog(@"setupAudioSession");

    return;
}

in my CXAnswerCallAction:

  func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
        print("Provider - CXAnswerCallAction")

        // get the active call
        guard let call = self.softphone.getCallForCallId(self.currentCallId) else {
            action.fail()
            return
        }

        /*
         Configure the audio session, but do not start call audio here, since it must be done once
         the audio session has been activated by the system after having its priority elevated.
         */
        self.softphone.configureAudioSession()

        // Trigger the call to be answered via the underlying network service.
        call.answer()

        // Signal to the system that the action has been successfully performed.
        action.fulfill()
    }

According to the documentation, didActivate should be called back by the callkit:

func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
    print("Provider - Received \(#function)")

    // Start call audio media, now that the audio session has been activated after having its priority boosted.
}

For some reasons, it's not called back after the first VOIP call. The subsequent calls seem to receive the callback and they work fine.

How to fix this?

like image 735
ssk Avatar asked Oct 30 '22 15:10

ssk


1 Answers

I've fixed this problem by setting call audio first then call "reportNewIncomingCall" method. Sample code is given below:

func reportIncomingCall(uuid: UUID, handle: String, hasVideo: Bool = false, completion: ((NSError?) -> Void)? = nil) {
    let update = CXCallUpdate()
    update.remoteHandle = CXHandle(type: .phoneNumber, value: handle)
    update.hasVideo = hasVideo


    DispatchQueue.global().sync {
        _ = try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, with: AVAudioSessionCategoryOptions.mixWithOthers)
        _ = try? AVAudioSession.sharedInstance().overrideOutputAudioPort(AVAudioSessionPortOverride.none)
        if hasVideo == true {
            _ = try? AVAudioSession.sharedInstance().setMode(AVAudioSessionModeVideoChat)
        } else {
            _ = try? AVAudioSession.sharedInstance().setMode(AVAudioSessionModeVoiceChat)
        }


        do {
            _ = try AVAudioSession.sharedInstance().setActive(true)
        } catch (let error){
            print("audio session error: \(error)")
        }
    }

    provider.reportNewIncomingCall(with: uuid, update: update) { error in

        if error == nil {

        }

        completion?(error as? NSError)
    }
}
like image 59
Nasser Munshi Avatar answered Nov 13 '22 16:11

Nasser Munshi