0

我正在开发一个 Cocoapod 库,我必须在计时器触发时调用一个函数。我在 iOS 应用程序中使用那个 Cocoapod,当应用程序进入后台状态时计时器没有触发

private var timer : DispatchSourceTimer? = nil

let queue = DispatchQueue(label: "sample.timer")
timer = DispatchSource.makeTimerSource(queue : queue)
timer?.setEventHandler 
{
    [weak self] in
    self?.sendData()
}
timer?.scheduleRepeating(deadline: .now(), interval: .seconds(5))
4

2 回答 2

3

您正在使用 GCD 计时器(Timer可以在后台线程上运行的替代方案)这一事实让我想知道您是否将“背景”一词的两种完全不同的用法混为一谈:

  • “后台”的一个含义与应用程序运行时的后台队列或线程有关。这与“主”线程/队列形成对比。

    而且,是的,GCD 计时器与Timer实例不同,因为它们可以在后台队列上运行(假设应用程序本身实际上正在运行)。

  • “背景”的另一个含义与应用程序的状态有关。您可以在前台运行、在后台运行或被挂起/终止。

    当应用程序运行时(在前台或后台),计时器(GCD 计时器或标准计时器Timer)可以运行。但是如果一个应用程序被暂停或终止,所有的执行都将停止,包括计时器。

问题是您正在尝试在应用程序本身已暂停时运行计时器。那不管用。

您的应用程序不会在后台运行,除非您:

  • 请求一点时间来完成一些有限长度的任务(在最近的 iOS 版本中只运行 30 秒);或者

  • 您的应用启用了一些后台模式,用于某些经过批准的用途(例如导航、音乐、VOIP 等)。

但是应用程序不能继续在后台运行(计时器或其他任何东西),除了那些特殊的、狭窄的情况(例如 VOIP、音乐、导航应用程序等)。有关后台执行的更多信息,请参阅:

而且,即使在允许更通用的后台任务的 iOS 13 及更高版本中,它们也适用于有限长度的任务,这些任务将由操作系统自行决定(由电源、wifi、用户启动的频率决定)应用程序等)。更多信息,请参阅 WWDC 2019应用后台执行进展

于 2018-03-28T17:08:17.263 回答
-1

这有点 hacky,但您可以尝试限制您在后台的时间并解决此问题。

import AVFoundation

do {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, with: .mixWithOthers)
    try AVAudioSession.sharedInstance().setActive(true)
}
catch { print(error) }
于 2018-03-28T17:17:31.087 回答