1

I have and application which give data usage in intervals. I want to detect if the device has been rebooted before using the data usage. I tried using mach_absolute_time() but i could not understand anything.Is it possible?

Amon
  • 99
  • 1
  • 9

2 Answers2

1

You can get the system uptime like this:

let systemUptime = NSProcessInfo.processInfo().systemUptime; // swift
NSTimeInterval timeInterval = [NSProcessInfo processInfo].systemUptime; //Objective c

You can store it in NSUserDefaults and use it to determine if a reboot occurred.

Please also check this thread for more information.

Swift 3:

let systemUptime: TimeInterval = ProcessInfo.processInfo.systemUptime
Maroš Beťko
  • 2,181
  • 2
  • 16
  • 42
vbgd
  • 1,937
  • 1
  • 13
  • 18
  • 2
    All those techniques detect a reboot when the user changes the phone's date/time. These techniques would only work with a reliable system boot timestamp, and if that information were available, there would be no need of these hacks. – piojo Sep 19 '16 at 10:31
  • 1
    @piojo That information is not explicitly available, but it can be easily calculated; see my answer below – Albert Renshaw Jul 18 '18 at 04:48
-1

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!

#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."_. 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:25
  • 1
    @AshleyMills Our app supports iOS6+ so we need to have synchronize incase user enters background shortly after (attempting to force quit app to bypass device reset detection). Synchronize only became un-necessary after iOS7. Please don't downvote for things like this – Albert Renshaw Oct 11 '18 at 18:07