iOS Swift Timer in not firing if the App is in the background

穿精又带淫゛_ 提交于 2020-07-08 03:44:43

问题


I am developing a Cocoapod library in which, i have to Call a function when timer fires. I am using that Cocoapod in an iOS App, Timer is not firing when App goes to background state

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

回答1:


The fact that you are using a GCD timer (an alternative to Timer that can run on background threads) makes me wonder if you are conflating two completely different uses of the word “background”:

  • One meaning of “background” is related to background queues or threads while an app is running. This is in contrast to the “main” thread/queue.

    And, yes, GCD timers are different than Timer instances insofar as they can run on background queues (assuming the app, itself, is actually running).

  • The other meaning of “background” is related to the state of an application. You can either be running in the foreground, running in the background, or be suspended/terminated.

    While an app is running (either in the foreground or the background), timers (either GCD timers or standard Timer) can operate. But if an app is suspended or terminated, all execution will stop, including timers.

The problem is that you’re trying to run a timer while the app, itself, has been suspended. That will not work.

Your app will not run in the background unless you either:

  • request a little time to finish some finite length task (which, IIRC, only runs for 3 minutes); or

  • your app has some background mode enabled for some approved purpose (e.g. navigation, music, VOIP, etc.).

But apps can’t continue to run in the background (timers or anything else), except for those special, narrow situations (e.g. VOIP, music, navigation apps, etc.). For more information about background execution see:

  • Managing Your App's Life Cycle
  • About the Background Execution Sequence

And, even in iOS 13 and later, where more generalized background tasks are permitted, they’re intended for finite length tasks that will be initiated at the sole discretion of the OS (determined by power, wifi, frequency with which the user fires up the app, etc.). For more information, see WWDC 2019 Advances in App Background Execution.




回答2:


It's a little hacky, but you can try to limit your time in the background and workaround this problem.

import AVFoundation

do {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, with: .mixWithOthers)
    try AVAudioSession.sharedInstance().setActive(true)
}
catch { print(error) }


来源:https://stackoverflow.com/questions/49526872/ios-swift-timer-in-not-firing-if-the-app-is-in-the-background

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!