ios - 当接听来电时,音频似乎无法与 CallKit 配合使用

标签 ios swift voip avaudiosession callkit

我将我的应用与 CallKit 集成,以便使用 VoIP 接收其他用户的来电。现在我面临一些音频问题,当接听电话时无法激活音频。

我已经检查过本教程This我比较了 ProviderDelegate ,它非常相似。

这就是我的 ProviderDelegate 类的样子

class ProviderDelegate: NSObject {
// 1.
fileprivate let callKitManager: CallKitCallInit
fileprivate let provider: CXProvider

init(callKitManager: CallKitCallInit) {
    self.callKitManager = callKitManager
    // 2.
    provider = CXProvider(configuration: type(of: self).providerConfiguration)
    
    super.init()
    // 3.
    provider.setDelegate(self, queue: nil)
    
}

// 4.
static var providerConfiguration: CXProviderConfiguration {
    let providerConfiguration = CXProviderConfiguration(localizedName: "vKclub dev2")
    
    providerConfiguration.supportsVideo = false
    providerConfiguration.maximumCallsPerCallGroup = 1
    providerConfiguration.supportedHandleTypes = [.phoneNumber]
    return providerConfiguration
}

func reportIncomingCall(uuid: UUID, handle: String, hasVideo: Bool = false, completion: ((NSError?) -> Void)?) {
    // 1.
    print("This is UUID === ", uuid)
    configureAudioSession()
    let update = CXCallUpdate()
    update.remoteHandle = CXHandle(type: .phoneNumber, value: handle)
    update.hasVideo = hasVideo
    

    provider.reportNewIncomingCall(with: uuid, update: update) { error in
        
        
        if error == nil {
            
            self.configureAudioSession()
            let call = CallKitCallInit(uuid: uuid, handle: handle)
            self.callKitManager.add(call: call)
            lastCallUUID = uuid
            print("UUID === ", uuid)
        } else {
            
        }
        
       
        completion?(error as NSError?)
    }
    
    
}

}

这就是我设置AVAudioSession

的方式
extension ProviderDelegate: CXProviderDelegate {

func providerDidReset(_ provider: CXProvider) {
    print("Stop Audio ==STOP-AUDIO==")
    
    for call in callKitManager.calls {
        call.end(uuid: UUID())
    }
    
    callKitManager.removeAllCalls()
}
func provider(_ provider: CXProvider, perform action: CXStartCallAction) {
    // 1.
    guard let call = callKitManager.callWithUUID(uuid: action.callUUID) else {
        action.fail()
        return
    }
    
    configureAudioSession()
    
}
func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
    // 1.
    guard let call = callKitManager.callWithUUID(uuid: action.callUUID) else {
        action.fail()
        return
    }
    // 2.
    configureAudioSession()
    // 3.
    call.answer()
    // 4.
    if #available(iOS 11, *) {
        print ("vKclub")
    } else {
        
        action.fulfill()
    }
    
}

func provider(_ provider: CXProvider, perform action: CXEndCallAction) {
    // 1.
    guard let call = callKitManager.callWithUUID(uuid: action.callUUID) else {
        action.fail()       
        return
    }
    // 2.
    print("Stop audio ==STOP-AUDIO==")
    configureAudioSession()
    // 3.
    call.end(uuid: action.callUUID)
    // 4.
    if #available(iOS 11, *) {
        print("Our vKclube")
    } else {
        action.fulfill()
    }
    
    // 5.
    callKitManager.remove(call: call)
}

// 5.
func provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession) {
    print("Starting audio ==STARTING-AUDIO==")
}


func provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) {
    print("Received \(#function)")
}

func configureAudioSession() {
    let session = AVAudioSession.sharedInstance()

    do{
        try session.setCategory(AVAudioSessionCategoryPlayAndRecord,
                                 mode: AVAudioSessionModeVoiceChat,
                                 options: [])

    } catch {
        print("========== Error in setting category \(error.localizedDescription)")
    }
    
    do {
        try session.setPreferredSampleRate(44100.0)
    } catch {
        print("======== Error setting rate \(error.localizedDescription)")
    }
    do {
        try session.setPreferredIOBufferDuration(0.005)
    } catch {
        print("======== Error IOBufferDuration \(error.localizedDescription)")
    }
    do {
        try session.setActive(true)
    } catch {
        print("========== Error starting session \(error.localizedDescription)")
    }
}

}

我已经面对这个问题好几天了,但我仍然无法弄清楚。 我正在使用 XCode 10.1。

最佳答案

我发现错误与您的代码 action.fulfill() 从未被调用有关。

基于Apple的文档:

调用此方法会将 isComplete 属性值设置为 true。多次调用该方法或在调用fail()方法后调用该方法没有任何效果。 您应该仅从 CXProviderDelegate 方法的实现中调用此方法。

我希望您应该在 CXProviderDelegate 中调用此方法。我已经看到你实现了它,但遗憾的是该方法从未被调用。我确信这就是您的音频未激活的原因。

关于ios - 当接听来电时,音频似乎无法与 CallKit 配合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54007207/

相关文章:

html - UIWebView 中讨厌的事件点击可视化

ios - UITableViewController : Update cell from DOWNLOADING to DONE

ios - RxSwift - 无法推断通用参数 'Self'

ios - '? :' 表达式中的结果值具有不匹配的类型 '()' 和 'Bool'

windows-8 - 寻找集成到 Windows 应用商店应用程序中的 VoIP 解决方案

ios - FBLoginButton 不请求权限

ios - 无法登录 QuickBlox iOS 13

ios - fatal error : Index out of range when using UITableView with multiple sections

voip - VoIP 服务如何连接到固定电话?

安卓 SIP SSL