接听来电时,音频似乎不适用于 CallKit
Audio seems not work with CallKit when incoming call is answered
我将我的应用程序与 CallKit
集成,以便使用 VoIP
接听其他用户的来电。现在我遇到了一些音频问题,接听电话时无法激活它。
我已经检查了本教程 This 并且我比较了 ProviderDelegate
这非常相似。
这就是我的 ProviderDelegate
class 的样子
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中调用这个方法。我已经看到您实现了它,但遗憾的是该方法从未被调用过。我确定这就是您的音频未激活的原因。
我将我的应用程序与 CallKit
集成,以便使用 VoIP
接听其他用户的来电。现在我遇到了一些音频问题,接听电话时无法激活它。
我已经检查了本教程 This 并且我比较了 ProviderDelegate
这非常相似。
这就是我的 ProviderDelegate
class 的样子
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中调用这个方法。我已经看到您实现了它,但遗憾的是该方法从未被调用过。我确定这就是您的音频未激活的原因。