When I write code for a timer like below, the timer doesn't fire if the device is locked. How do I cause the code in the timer closure to run when the app is in the background? Are there any other ways to cause specific code to run at a certain time when the app is in the background?
func setTimer(alarm: UTIAlarm) {
let timer = Timer(fire: alarm.date!, interval: 0, repeats: false) {
(timer: Timer) in
print("timer fire \(self.dateFormatter.string(from: alarm.date!))")
do {
try AVAudioSession.sharedInstance().setActive(true, options: .notifyOthersOnDeactivation)
} catch {
print("Failed to setActive AVAudioSession from timer closure.")
print(error.localizedDescription)
}
let predicate = MPMediaPropertyPredicate(value: alarm.mediaItem!.title, forProperty: MPMediaItemPropertyTitle)
let query = MPMediaQuery()
query.addFilterPredicate(predicate)
self.playerController!.setQueue(with: query)
self.playerController!.play()
}
runLoop.add(timer, forMode: .default)
timers.append(timer)
}
>I am not aware of any iOS API that will allow you to run code on a fixed schedule from the background.
This OP often posts similar questions on multiple boards. In one of those similar messages I responded that you could do this through remote notifications generated by your own server or through CloudKit.
see:
and also:
Use a CKQuerySubscription with a query that was satisfied by any file that was modifed in a particular CloudKit container after a particular time - e.g. 25 minutes from now, repeatedly. And then you could run, anywhere on the planet, an app that modifed a dummy file in that same CloudKit Zone every minute. That would trigger a remote notification associated with the subscription in 25 minutes. The remote notification would reset the subscription.