繁体   English   中英

CallKit:在 GSM 通话断开后恢复保持的 VoIP 通话

[英]CallKit: Resume an on hold VoIP call after GSM call disconnects

我遇到了一个问题,即在主叫方断开 GSM 呼叫后,我无法恢复暂停的 VoIP 呼叫。

工作正常的场景一

  1. 我接听 VoIP 来电
  2. 我接到一个 GSM 电话,按“保持并接受”,这导致provider(_ provider: CXProvider, perform action: CXSetHeldCallAction)被调用,允许我将 VoIP 通话置于保持状态
  3. 我挂断了导致provider(_ provider: CXProvider, perform action: CXSetHeldCallAction)被调用的 GSM 通话,允许我取消保留 VoIP 通话

场景二

  1. 我接听 VoIP 来电
  2. 我接到一个 GSM 电话,按“保持并接受”,这导致provider(_ provider: CXProvider, perform action: CXSetHeldCallAction)被调用,允许我将 VoIP 通话置于保持状态
  3. 主叫挂断GSM通话,但是provider(_ provider: CXProvider, perform action: CXSetHeldCallAction)没有被调用

在场景二中,呼叫者挂断 GSM 呼叫后,仅调用provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession)

如果provider(_ provider: CXProvider, perform action: CXSetHeldCallAction)未被调用,我们如何在呼叫者断开 GSM 后恢复 VoIP 呼叫?

public func provider(_ provider: CXProvider, perform action: CXSetHeldCallAction)
{
    print("Callkit: provider(_ provider: CXProvider, perform action: CXSetHeldCallAction): \(action.callUUID)")
        
    guard var call = callManager.call(withUUID: action.callUUID) else {
        action.fail()
        return
    }
        
    call.isOnHold = action.isOnHold
    call.isMuted = call.isOnHold
        
    audioRouter.audioDevice.isEnabled = !call.isOnHold
        
    action.fulfill()
}

GSM通话结束后,返回app时会调用applicationDidBecomeActive 此时,我们可以检测呼叫是否处于保持状态并恢复它。 欢迎其他解决方案。

我今天遇到了这个。 经过一些谷歌搜索,我无法找到解决方案。 太奇怪了,我想,没有人能解决这个问题。 我能够找到受@Simon 启发的解决方案,但我认为更简洁一些。

在您的 CallViewController、AppDelegate 或类似内容中,将您自己设置为 CXCallObserver 的委托。

CXCallController.shared.callObserver.setDelegate(self, queue: .main)

然后,您想检测是否恰好有一个活动呼叫,它是“您的”(无论这对您意味着什么。对我来说,它存储在self.call.id中)并且它处于暂停状态。 如果是这样,您可以请求更新以“取消保留”它,并且您在其他地方处理func provider(_ provider: CXProvider, perform action: CXSetHeldCallAction)的代码将被调用,并希望您的应用程序正确处理它。

  //MARK: - CXCallObserverDelegate
  
  func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) {
    guard let activeCall = callObserver.calls.first,
          1 == callObserver.calls.count,
          activeCall.uuid == self.call.id,
          true == activeCall.isOnHold else {
      return
    }
    let transaction = CXTransaction(action: CXSetHeldCallAction(call: activeCall.uuid, onHold: false))
    CXCallController.shared.request(transaction) { error in
      if let error = error {
        //handle it?
      }
    }
  }

当您接到来自 WhatsApp 的来电,并且您的应用程序被搁置时, CXCallObserver.shared.calls将返回两个呼叫。 一个将是“您的”暂停,另一个将是“WhatsApp 通话”而不是暂停。 一旦 WhatsApp 呼叫在另一端终止, CXCallObserver.shared.calls将只返回一个呼叫,即您的呼叫,但仍将处于保持状态。 这似乎是 CallKit 中一个相当严重的错误。 但我知道什么?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM