问题
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