CallKit & AVAudioSessionErrorCodeMissingEntitlement

I'm integrating CallKit in a VoIP app and one of the integration points is letting CallKit activate audio session on behalf of the app.

Sadly, a lot of times there is no audio because AudioUnitInitialize returns a AVAudioSessionErrorCodeMissingEntitlement error. Sometimes it works, sometimes it doesn't.

This happens using the beta 6 (and before) in the Speakerbox example app, even with the “requires background audio” entitlement checked. Our app already had that entitlement and it is also seeing this error. Has anyone encounter this error?


Already filed a radar on this: rdar://27674736 http://www.openradar.me/27674736

Accepted Reply

There is a workaround for this problem: Instead of configuring AudioSession in perform:AnswerCallAction, as recommended in the demo of WWDC Session 230, do it in the completion handler of reportNewIncomingCall(with:update:completion:).


provider.reportNewIncomingCall(with: uuid, update: update) { error in
    if error == nil {
        configureAudioSession()
    }
}


The problem could be a race condition, since it happens randomly and a lot more often in slower devices: on iPhone 5S the problem appears on more than 50% of the incoming calls, both in SpeakerBox and in our app.

Replies

There is a workaround for this problem: Instead of configuring AudioSession in perform:AnswerCallAction, as recommended in the demo of WWDC Session 230, do it in the completion handler of reportNewIncomingCall(with:update:completion:).


provider.reportNewIncomingCall(with: uuid, update: update) { error in
    if error == nil {
        configureAudioSession()
    }
}


The problem could be a race condition, since it happens randomly and a lot more often in slower devices: on iPhone 5S the problem appears on more than 50% of the incoming calls, both in SpeakerBox and in our app.

I encountered the same issue on iOS 10.0.2. Moving the call of configureAudioSession() into reportNewIncomingCall() didn't help in my case. Instead, I moved AudioUnitInitialize into the provider didActivateAudioSession callback, it seems to work fine.

I tried this and it did not work for me, either.


After further experienmentation I do indeed have it working now.

You have to restore audio session category after incoming call receiving:

was AVAudioSessionCategorySoloAmbient -> must AVAudioSessionCategoryPlayAndRecord


It works with webrtc


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


// Workaround for webrtc, because first incoming call does not have audio due to incorrect category: AVAudioSessionCategorySoloAmbient

// webrtc need AVAudioSessionCategoryPlayAndRecord

do {

try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord)

catch let error {

DDLogInfo("AVAudioSession setCategory ERROR: \(error)")

}

......