使用 CTCallCenter (Swift) 在 iOS 上检测电话

Detect phone calls on iOS with CTCallCenter (Swift)

我想尝试在我的应用中检测来电。我从头开始创建了一个新的 Swift 项目,只是为了尝试一些代码。我唯一做的就是在每个新项目创建的 ViewController 中导入 CoreTelephony,我还将 viewDidLoad() 更改为:

1
2
3
4
5
6
7
8
9
10
11
12
13
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    let callCenter = CTCallCenter()
    NSLog("start")

    callCenter.callEventHandler = {[weak self] (call: CTCall) -> () in

        self?.label.text = call.callState
        NSLog("Call state")
        NSLog(call.callState)

    }

我也尝试过不使用 [weak self],因为我是 swift 新手,不确定它的含义。

当我通过手机上的 XCode 运行我的新小应用程序时,当接到电话、断开连接或其他任何事情时,什么都没有发生。从来没有错误。为了使用 CoreTelephony 框架和 CTCallCenter,我是否需要做更多的事情?

问候
约翰


callEventHandler 已从 iOS 10 开始弃用。

iOS 10 现在采用了一个新框架来完成您的任务,CallKit。这是 Apple 的新框架,可以处理所有电话中断。要检测来电和去电,请使用 CXCallObserver。此类使用协议 CXCallObserverDelegate 通知已注册的委托调用的更改。我发现它可以很好地将 AppDelegate 设置为委托。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// AppDelegate
var callObserver: CXCallObserver!

// in applicationDidFinishLaunching...
callObserver = CXCallObserver()
callObserver.setDelegate(self, queue: nil) // nil queue means main thread

extension AppDelegate: CXCallObserverDelegate {
    func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) {
        if call.hasEnded == true {
            print("Disconnected")
        }
        if call.isOutgoing == true && call.hasConnected == false {
            print("Dialing")
        }
        if call.isOutgoing == false && call.hasConnected == false && call.hasEnded == false {
            print("Incoming")
        }

        if call.hasConnected == true && call.hasEnded == false {
            print("Connected")
        }
    }
}


这是我上面评论的扩展。

Try making callCenter a property of your view controller instead of just a variable in viewDidLoad.

当您在方法中定义变量时,该变量及其值仅存在于该方法中。当方法完成运行时,有价值的和它们的值被清除,所以它们不会继续使用内存(除非该值在别处使用)。

在您的情况下,您定义 callCenter 并为其分配一个新的 CTCallCenter 实例。但是在 viewDidLoad 结束时, CTCallCenter 实例不再使用,因此它从内存中清除。由于它不再存在,它无法处理调用事件。

通过添加 callCenter 作为视图控制器的属性,它将 CTCallCenter 实例的生命周期与视图控制器的生命周期联系起来。所以 CTCallCenter 只会在视图控制器从内存中清除时才从内存中清除。

有关更多详细信息,请阅读 Swift 中的自动引用计数