6

Looking to see what people have come up with for this. Basically I want to know if the actual device has been rebooted since my app was last launched. What methods do people use to find this out? (If any?)

I've considered using mach_absolute_time but this is still an unreliable method.

Cheers

Aron
  • 555
  • 6
  • 12

2 Answers2

5

Not sure sure if this is what you wanted but have a look at this:

https://github.com/pfeilbr/ios-system-uptime

In this example the author fetches it from the kernel task process.

Or you could look take the mach_absolute_time route, there is an official Apple Q&A with a similar aim https://developer.apple.com/library/mac/#qa/qa1398/_index.html

Hope this helps.

Alex Stuckey
  • 1,250
  • 1
  • 14
  • 28
  • Hi Alex, i'll give the kernel task process uptime a shot. I'll let you know how i go! – Aron Oct 30 '12 at 01:10
  • At the risk of sounding dumb, what's the difference between this and CACurrentMediaTime()? My understanding of this function is it returns mach_absolute_time reliably converted into seconds (mach_absolute_time being the amount of time since the device has restarted) Is that correct? – Aron Oct 31 '12 at 00:24
  • @Aron, sorry but I don't know too much about this. Just read the Apple Q&A. How did the kernel task process method go? Any luck? – Alex Stuckey Oct 31 '12 at 00:36
  • I ended up using the mach_absolute_time method through CACurrentMediaTime(). I was able to calculate the last restart time using CACurrentMediaTime() (essentially a convenience method for mach_absolute_time) and LastTimeIntervalSince1970. Comparing this with a cached value will allow me to determine if the device has been restarted or not. – Aron Oct 31 '12 at 03:37
0

Here is one I made. It takes the current time in GMT and the time since last reboot to extrapolate a date for when the device was last restarted. Then it keeps track of this date in memory using NSUserDefaults. Enjoy!

Note: Since you want to check this since last time app was launched, you need to make sure you call the method anytime the app is launched. The easiest way would be to call the method below in +(void)initialize { and then also whenever you need to check it manually

#define nowInSeconds CFAbsoluteTimeGetCurrent()//since Jan 1 2001 00:00:00 GMT
#define secondsSinceDeviceRestart ((int)round([[NSProcessInfo processInfo] systemUptime]))
#define storage [NSUserDefaults standardUserDefaults]
#define DISTANCE(valueOne, valueTwo) ((((valueOne)-(valueTwo))>=0)?((valueOne)-(valueTwo)):((valueTwo)-(valueOne)))

+(BOOL)didDeviceReset {
    static BOOL didDeviceReset;
    static dispatch_once_t onceToken;
    int currentRestartDate = nowInSeconds-secondsSinceDeviceRestart;
    int previousRestartDate = (int)[((NSNumber *)[storage objectForKey:@"previousRestartDate"]) integerValue];
    int dateVarianceThreshold = 10;
    dispatch_once(&onceToken, ^{
        if (!previousRestartDate || DISTANCE(currentRestartDate, previousRestartDate) > dateVarianceThreshold) {
            didDeviceReset = YES;
        } else {
            didDeviceReset = NO;
        }
    });
    [storage setObject:@(currentRestartDate) forKey:@"previousRestartDate"];
    [storage synchronize];
    return didDeviceReset;
}
Albert Renshaw
  • 17,282
  • 18
  • 107
  • 195
  • Don't use `-[NSUserDefaults synchronize]`. From [Apple's documentation](https://developer.apple.com/documentation/foundation/nsuserdefaults/1414005-synchronize?language=objc) _"this method is unnecessary and shouldn't be used."_ – Ashley Mills Oct 11 '18 at 14:22
  • Also, don't give the same answer to multiple questions. Just provide a link in the comments. https://stackoverflow.com/a/51391327/123632 – Ashley Mills Oct 11 '18 at 14:24