I have static library code from which I'm attempting to use NSProcessInfo.performExpiringActivity() to ensure that our app isn't background-terminated in the middle of a relatively short (yet important) periodic background task. However, what's currently tripping me up is how NSProcessInfo.performExpiringActivity()'s block can be invoked more than once:
let queue: DispatchQueue = DispatchQueue(label: "com.my-company.ios.foo", qos: .utility)
let timer = DispatchSource.makeTimerSource(queue: queue)
timer.setEventHandler { [weak self] in
guard let self = self, let managedObjectContext = self.managedObjectContext else {
timer.cancel()
return
}
timer.suspend()
ProcessInfo.processInfo.performExpiringActivity(withReason: "Performing activity") { expired in
defer {
timer.resume()
}
guard !expired else {
return
}
managedObjectContext.performAndWait {
...
}
}
}
In this case, if the block is called a second time, the timer will be over-resumed and result in a crash. I could add more book-keeping variables to guard against this, but it'll certainly make the code more difficult to maintain and reason about.
Is there a more elegant and/or correct way to do this? (Links to sample code or write-ups would be appreciated!)