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

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") } } } 

和函数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) } }) 

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

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

是。

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

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

1) 背景执行

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

2) 背景模式

在此处输入图像描述

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

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


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

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

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

我无法使用Push Kit因为其目的是获取普通GSM呼叫的事件而不是voip呼叫。

我认为CallKit不再允许我们区分呼叫类型。 它会触发事件但是,我们将无法过滤出细胞事件。

此问题更详细地讨论了事件触发器: 调用状态

希望6月份的这种变化和Apple可能会在CallKit中添加新的function。

亲切的问候,

木孔德

答案是BIG NO,你无法获得有关呼叫/ GSM数据的信息,Call kit仅与VOIP有关。

PS:我假设VOIP电话是由您处理的

对于APNS / PushKit Payload,字典来自您的托管服务器。

只是你可以添加一个键值对isVOIPCall:true来区分。