iOS 如何在后台检测通话状态?

iOS How to detect call state in background?

我正在尝试根据通话状态更改按钮状态。 我使用此处的代码来检测呼叫状态:How to get a call event using CTCallCenter:setCallEventHandler: that occurred while the app was suspended?

当应用程序处于前台时,它工作正常。但它在后台根本不起作用。在 CTCallCenter.callEventHandler 的文档中:

When your application resumes the active state, it receives a single call event for each call that changed state—no matter how many state changes the call experienced while your application was suspended. The single call event sent to your handler, upon your application returning to the active state, describes the call’s state at that time.

但是当应用程序恢复活动时,我没有收到任何呼叫事件。当应用程序处于前台时,我得到的只是最后保存的呼叫状态。如何在后台检测通话状态?

这是我的代码:

AppDelegate.swift

  let callСenter = CTCallCenter()

    func block (call:CTCall!)
    {
        callState = String(call.callState)
        print(call.callState)
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
    {
        //check for call state
        callСenter.callEventHandler = block

...

        return true
    }

ViewController.swift

 override func viewDidLoad()
    {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(
            self,
            selector: #selector(cameBackFromSleep),
            name: NSNotification.Name.UIApplicationDidBecomeActive,
            object: nil
        )

        ...
    }

    func cameBackFromSleep()
    {
        self.viewWillAppear(true)
    }

    override func viewWillAppear(_ animated: Bool)
    {
        switch callState
        {
        case "CTCallStateConnected":
            print("callState: ", callState)
            self.textLabel.isHidden = true
            startBtnAnimation()
        case "CTCallStateDisconnected":
            print("callState: ", callState)
            self.textLabel.center.y += self.view.bounds.height
            self.textLabel.isHidden = false
            stopBtnAnimation()
        default: break
        }
    }

我终于解决了!我使用了这个答案中的代码:

我删除了 AppDelegate 中的所有内容,所有工作都在 ViewController 中完成:

override func viewDidLoad()
    {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(
            self,
            selector: #selector(cameBackFromSleep),
            name: NSNotification.Name.UIApplicationDidBecomeActive,
            object: nil
        )

...

    }

    private func isOnPhoneCall() -> Bool
    {
        let callCntr = CTCallCenter()

        if let calls = callCntr.currentCalls
        {
            for call in calls
            {
                if call.callState == CTCallStateConnected || call.callState == CTCallStateDialing || call.callState == CTCallStateIncoming
                {
                    print("In call")
                    return true
                }
            }
        }

        print("No calls")
        return false
    }

    func cameBackFromSleep()
    {

        self.viewWillAppear(true)
    }

    override func viewWillAppear(_ animated: Bool)
    {
        print("is on call", isOnPhoneCall())
        switch isOnPhoneCall()
        {
        case true:
            print("startBtnAnimation")
            startBtnAnimation()
            recordBtnIsPressed = true
        case false:
            print("stopBtnAnimation")
            stopBtnAnimation()
            recordBtnIsPressed = false
        default: break
        }
    }

现在可以正常使用了。不确定为什么 CTCallCenterAppDelegate 中工作如此奇怪。