I thought the difference between DispatchTime and DispatchWallTime had to do with whether the app was suspended or the device screen was locked or something: DispatchTime should pause, whereas DispatchWallTime should keep going because clocks in the real world keep going.
So I wrote a little test app:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationDidEnterBackground(_ application: UIApplication) {
print("backgrounding the app, starting timers for 60 seconds", Date())
DispatchQueue.main.asyncAfter(deadline: .now() + 60) {
print("deadline 60 seconds ended", Date())
}
DispatchQueue.main.asyncAfter(wallDeadline: .now() + 60) {
print("wallDeadline 60 seconds ended", Date())
}
}
func applicationWillEnterForeground(_ application: UIApplication) {
print("app coming to front", Date())
}
}
I ran the app on my device. I backgrounded the app, waited for a while, then brought the app to the foreground. Sometimes "waited for a while" included switching off the screen. I got results like this:
backgrounding the app, starting timers for 60 seconds 2018-08-15 17:41:18 +0000
app coming to front 2018-08-15 17:41:58 +0000
wallDeadline 60 seconds ended 2018-08-15 17:42:24 +0000
deadline 60 seconds ended 2018-08-15 17:42:24 +0000
backgrounding the app, starting timers for 60 seconds 2018-08-15 17:42:49 +0000
app coming to front 2018-08-15 17:43:21 +0000
wallDeadline 60 seconds ended 2018-08-15 17:43:55 +0000
deadline 60 seconds ended 2018-08-15 17:43:55 +0000
The delay before the deadline
timer fires is not as long as I expected: it's 6 seconds over the 60 second deadline, even though I "slept" the app for considerably longer than that. But even more surprising, both timers fire at the same instant.
So what does wallDeadline
do on iOS that's different from what deadline
does?
This question has been here for quite a while without any answers, so I'd like to give it a try and point out subtle difference I noticed in practice.
DispatchTime should pause, whereas DispatchWallTime should keep going because clocks in the real world keep going
You are correct here, at least they are supposed to work this way. It's really tricky to check that DispatchTime
suspends, though: when an iOS app is running under Xcode debugging session, it has unlimited background time and isn't getting suspended. Moreover, even when playing around with the app without Xcode connected, I could not confirm that DispatchTime
is paused under whatever conditions. I found, however, that there is another key property: DispatchTime
doesn't depend on the system clock. DispatchWallTime
works pretty much the same (and I couldn't confirm that it gets paused either), with exception to that it depends on the system clock.
In order to see the difference, you can try out a little longer timer, say, 5 minutes. After that go to the system settings and set the time 1 hour forward. If you now open the application you can notice, that DispatchWallTime
immediately expires whereas DispatchTime
keeps waiting for its time to come