Search code examples
swifttokboxcallkit

CallKit - How to bring the CXCallController to the front


I'm creating a VOIP App. Most of the logic is similar to the Raywenderlich Tutorial.

My issue is that after accepting the call, the CXCallController is not on top of the App, but next to it in the "task manager":

enter image description here

The problem with that is, that once you have accepted the call, the CXCallController is not the top most controller, but the actual App. So you can't tell that the call is taking place. And to perform actions regarding the call - for example hang up, hold, mute you would have to go through the task manager to open the CXCallController. Not very user friendly.

How do I bring the CXCallController to the front after the user has accepted the call?

Provider delegate called after the user has answered the call:

func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {

    guard let call = callManager.getCall(with: action.callUUID) else {
        action.fail()
        return
    }

    configureAudioSession()
    self.incommingCall = call
    action.fulfill()
}

Callback after the audio session has been created:

func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {

    incommingCall?.answerCall(with: audioSession) { success in

        if success {
            self.incommingCall?.startAudio()
        }
    }
}

Start call logic using TokBox VOIP Service:

func answerCall(with audioSession: AVAudioSession, completion: ((_ success: Bool) -> Void)?) {

    OTAudioDeviceManager.setAudioDevice(OTDefaultAudioDevice.sharedInstance(with: audioSession))
    if session == nil {
        session = OTSession(apiKey: self.apiKey, sessionId: self.sessionID, delegate: self)
    }

    answerCallCompletion = completion

    var error: OTError?
    hasStartedConnecting = true
    session?.connect(withToken: self.token, error: &error)

    if error != nil {

        CoreServices.catchError(error: error, at: #function)
    }
}

The call itself works fine. Two parties are able to communicate, start and end calls. The only issue is the described CXCallController behavior.

Is this expected behavior? Or how do I bring the CXCallController to the front? Help is very appreciated.


Solution

  • This is the expected behaviour of the callkit. Callkit allows us to answer or decline the call when the app is receiving the incoming call. After answering the call, the app has to manage all the actions.

    • when the phone is locked, receive the incoming call, CXCallController will be visible, after answering the call, still you can see the CXCallController in the lock mode. After unlocking the phone, CXCallController will be invisible, the app has to manage the hangup, mute or hold options.
    • when the phone is not locked, receive the incoming call, CXCallController will be visible, after answering the call, CXCallController will be invisible, the app has to manage the hangup, mute or hold options.