检测IOS 10中的GSM呼叫状态(Swift 3,Xcode 8)和来自后台状态的通知

Why*_*Why 13 ios core-telephony swift ios10 callkit

TLDR:从后台检测呼叫结束事件 请参阅以下问题的更新:

是否可以使用Swift从后台状态检测/获取IOS 10中的呼叫状态事件.在早期版本中有一个CORE Telephony api,但现在似乎已经弃用了.

我见过CallKit Api, 但它说这是基于VOIP的呼叫.我需要获得正常的CDMA/GSM呼叫状态,而不是基于VOIP的呼叫,并且当呼叫结束时只需向服务器发出通知.我不需要访问任何可能是隐私问题的数据点,只需要一个事件,当呼叫结束时,然后我的应用程序将是一个后台应用程序将启动.而已.有关如何做到这一点的任何指示?

更新:使用CallKit Api虽然无法区分voip和普通的GSM呼叫,但我能够获得呼叫状态.我可以解决这个问题.我也可以通过以下方式获得本地通知.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        application.beginBackgroundTask(withName: "showN", expirationHandler:nil)
        return true
    }

extension AppDelegate: CXCallObserverDelegate {
       func callObserver(_ callObserver: CXCallObserver, callChanged call: CXCall) {
        if call.hasEnded == true {
            print("Disconnected")
            let trigger = UNTimeIntervalNotificationTrigger(timeInterval:60,repeats:false)
            let identifier = "MyCallLocalNotification"
            let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
            center.add(request, withCompletionHandler: { (error) in
                if let error = error{
                    print(error)
                }
            })
            Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(AppDelegate.showN), userInfo: nil, repeats: false)
            print("Done")
        }
        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")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

和函数showN为:

func showN(){
        let identifier = "MyCallLocalNotification"
        let trigger = UNTimeIntervalNotificationTrigger(timeInterval:1,repeats:false)
        let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)
        center.add(request, withCompletionHandler: { (error) in
            if let error = error{
                print(error)
            }
        })
Run Code Online (Sandbox Code Playgroud)

但是(正如预期的那样),当应用程序在后台长时间(超过3分钟)或屏幕被锁定时,这不起作用.我觉得我几乎在那里,但遗漏了一些东西.另外认为这不是一种正确的方法,或者必须有更好的(快速/ IOS标准)方法来做到这一点.请建议.已经失去了50个赏金点:)

Bra*_*n A 5

"是否可以使用Swift从后台状态检测/获取IOS 10中的呼叫状态事件"

是.

您申请的背景状态只是暂停进入暂停状态.发生这种情况时,系统将停止代码尝试响应的所有进程.

Apple这样做是有充分理由的.它们不是用户不用于在设备上吃掉电池的应用程序.如果他们没有这样做,你的iPhone电池将很快耗尽.因此,要强制执行此操作,所有仍处于后台状态的应用程序最终将被暂停.当然,除非您以几种不同的方式配置应用程序.

1)背景执行

看起来你可能已经在你的应用程序中做了这件事.但这将允许您的应用程序执行任何可能尚未完成或需要稍微扩展的长时间运行的任务.正如您所知,这些后台任务的运行时间有限.您的应用程序暂停时不会执行.它将使您的应用程序保持在后台状态最多3分钟,以完成它的工作.一旦完成,您的应用程序将立即进入暂停状态.

2)背景模式

在此输入图像描述

使应用程序最可靠的方法仍然是后台状态,即在项目配置中启用一项功能,指示您的应用程序使用有效的后台模式.我的应用Sublam这样做.它是一个音乐播放器应用程序,可以增强iTunes中的音乐,使其发声最佳.如果用户只能在应用程序处于前台时听音乐,那将非常烦人.几乎保持囚犯,永远不能离开或音乐会停止.我启用了后台模式以使我的应用程序保持在后台并远离可怕的挂起状态.这样我的应用程序就可以处理用户输入以更改歌曲,暂停,播放或我的应用程序需要做出的任何其他操作.

您的应用程序需要符合有效的后台模式,以确保它保持在后台状态,并能够对任何进入的呼叫做出反应.否则,CXCallObserverDelegate方法根本不会执行.


"我需要获得正常的CDMA/GSM呼叫状态,而不是基于VOIP的呼叫"

正如Mukund和Raza所说 - 你不能使用CallKit来确定这些信息.希望这将成为CallKit未来的新功能.但截至目前,此功能尚不支持.


Why*_*Why 2

过了很长一段时间,这在 iOS 10 中似乎不太可行。我确实尝试过按照建议使用背景模式,但我既不需要播放音乐,也不需要一直跟踪位置,因此它们不适合我。

我无法使用Push Kit,因为目的是获取正常 GSM 呼叫而不是 VoIP 呼叫的事件。