clock_get_time/mach_absolute_time stops updating when device goes to sleep on iOS 7
Asked Answered
C

2

7

My application uses mach_absolute_time to calculate the ticks since the last touch event and logs the user out if it surpasses an idle time limit of 10 minutes.

This all works fine on iOS 6, but I noticed that it was not behaving correctly on iOS 7. Specifically, when the iOS 7 device is unplugged (on battery), it seems that the device stops incrementing its ticks once it goes to sleep following this line in the console (this happens after about 5 minutes of inactivity):

powerd[47] : Sleep: Using BATT (Charge:99%)

Therefore, when I wake the device up after 10 minutes, and calculate the ticks using mach_absolute_time, the difference shows to be only 5 minutes (when in reality, 10 minutes have passed).

Strangely enough, all works properly and the ticks continue to run when the device is plugged in to a power source. It never shows that the device is going to sleep on the console log when it is plugged in (although the screen does turn off and the behavior is the same visually as when unplugged).

I've tried this using clock_get_time as well, and I'm facing the same issue there.

Is there something I can do in iOS 7 to keep Mach absolute time ticking when the device goes to sleep? I don't want to use [[NSDate date] timeIntervalSince1970] as users are able to manipulate the system time and bypass this.

Thanks for any insights.

Cosmography answered 6/11, 2013 at 16:49 Comment(0)
C
2

Turns out the default behavior of mach_absolute_time() is to stop ticking once the device goes to sleep. On iOS 6 I was able to extend the time till suspension by 10 minutes when the app was put into the background using beginBackgroundTaskWithExpirationHandler. In iOS 7, however, the maximum time allowed for this has been capped at 3 minutes (found this out by calling backgroundTimeRemaining). This is why I was seeing the clock stop on iOS 7, but not on iOS 6.

Stumbled upon this answer today, which seems promising.

- (time_t)uptime {
    struct timeval boottime;
    int mib[2] = {CTL_KERN, KERN_BOOTTIME};
    size_t size = sizeof(boottime);
    time_t now;
    time_t uptime = -1;
    (void)time(&now);
    if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 && boottime.tv_sec != 0) {
        uptime = now - boottime.tv_sec;
    }
    return uptime;
}

time() carries on incrementing while the device is asleep, but of course can be manipulated by the operating system or user. However, the Kernel boottime (a timestamp of when the system last booted) also changes when the system clock is changed, therefore even though both these values are not fixed, the offset between them is.

Cosmography answered 7/11, 2013 at 18:50 Comment(4)
Then is there any way to resolve and allow the background thread to keep running over iOS7?Francois
Cool, you're also welcome to the similar source code here: #9565323Packston
@Francois I tried a few things, but it looks like it's a hard limit that cannot be extended. Documentation is spotty on this aside from the WWDC vieos. This is the best I found that mentions this decrease in background time allowed: developer.apple.com/library/ios/releasenotes/General/…Cosmography
You suggested an edit here: https://mcmap.net/q/117916/-why-is-a-div-with-quot-display-table-cell-quot-not-affected-by-margin. If you think there is something wrong with someone's code, and the user has visited within recent time, just leave a comment on the post, please.Deprive
R
2

You can nowadays use clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW) which includes the time spent asleep. In Swift:

import Foundation

let elapsed_time_nanos = clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW)

I can't find documentation for that function on the Apple website, but the docs for mach_continuous_time mention it.

Rakes answered 8/3, 2022 at 12:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.