Getting iOS System Uptime, That Doesn't Pause When Asleep

Getting iOS system uptime, that doesn't pause when asleep

I think I worked it out.

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.

#include 

- (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;
}

Getting system uptime in iOS/Swift

As you ask for a pure-Swift solution, I converted the ObjC code from the answer you mentioned Getting iOS system uptime, that doesn't pause when asleep.

func uptime() -> time_t {
var boottime = timeval()
var mib: [Int32] = [CTL_KERN, KERN_BOOTTIME]
var size = strideof(timeval)

var now = time_t()
var uptime: time_t = -1

time(&now)
if (sysctl(&mib, 2, &boottime, &size, nil, 0) != -1 && boottime.tv_sec != 0) {
uptime = now - boottime.tv_sec
}
return uptime
}

// print(uptime())

To make it a bit prettier, we can use sysctlbyname instead of sysctl:

// var mib: [Int32] = [CTL_KERN, KERN_BOOTTIME]
sysctlbyname("kern.boottime", &boottime, &size, nil, 0)

How to get exact time since iOS device booted?

After investigation of the data you provide. It is possible to conclude that CMLog​Item:

The CMLog​Item class is a base class for Core Motion classes that
handle specific types of motion events. Objects of this class
represent a piece of time-tagged data that can be logged to a file.

CMLog​Item defines only a read-only timestamp property that records the time a motion-event measurement was taken. Not the exact time since device was booted.

By ProcessInfo.processInfo.systemUptime you going to get time from the last time it was restarted.

I believe data that you would like to obtain is quite specific and is under Private API of the iOS.

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

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.

NSSystemClockDidChangeNotification acts weird when app wakes up

Like that: Getting iOS system uptime, that doesn't pause when asleep

But remember, this solution will fail sometimes because of out-of-sync when system tries to update time from NTP server when the Internet connection is not reachable.



Related Topics



Leave a reply



Submit