簡體   English   中英

自上次應用程序啟動以來,如何檢測iphone是否已重新啟動

[英]How can I detect whether the iphone has been rebooted since last time app started

我想從我的應用程序中檢測到自上次我的應用程序啟動以來iPhone是否已重新啟動。 我需要這樣做,因為我的應用程序使用自上次系統重啟后的計時器計時用戶的時間,我想檢測重啟,以便我可以使時間無效。

有沒有我可以從系統控制台日志中提取信息,如重啟,崩潰? xcode中的組織者可以訪問它,也許我也可以訪問它。

如果沒有,您能想到其他獲取此信息的方法嗎?

這似乎可行:

  • 得到自上次重啟以來的時間,對於這個例子,讓我們把它存儲在一個名為'tslr'的變量中(我猜想持續時間以毫秒為單位,BTW,你怎么做到的?)
  • 獲取當前時間,例如將其存儲在變量'ct'中
  • 計算最后一次重啟時間(我們稱之為'lr'),我們有:lr = ct - tslr
  • 商店'lr'

下次啟動應用程序時,加載“lr”的先前值,計算新值,如果它們不同,則檢測到重新啟動(您可能必須容忍一小段差別......也許幾毫秒)。

我認為愚弄這一點非常困難......用戶必須非常精確地篡改他們的手機時間,並且他們必須在非常精確的時刻啟動你的應用程序,正好在新的'lr'時與前一個相同......很難做到,我認為他們能夠做到這一點的概率非常接近0。 你不需要任何互聯網連接來做到這一點......

在以下情況下,新的'lr'將與前一個相同:

  • 手機沒有重啟,時間沒有改變
  • 時間被篡改,並且用戶設法以精確的毫秒啟動你的應用程序以欺騙你的算法(這種情況發生的可能性超過了超級)

佐蘭的答案是正確的方法; 它是沒有網絡連接的最接近的。 (出於安全原因,無法訪問蜂窩子系統和syslog)

如果您希望防止惡意用戶生成虛假時間數據,請讓一些中央服務器(或企業部署的可信本地服務器)跟蹤與時間相關的事件。

    // Returns true if device has rebooted since last time
    private func deviceRebootedSinceLastTime() -> Bool {
        let userDefaults = NSUserDefaults.standardUserDefaults()
        let systemUptime = NSProcessInfo.processInfo().systemUptime;
        let timeNow = NSDate().timeIntervalSince1970
        let dateOfLastReboot = NSDate(timeIntervalSince1970: timeNow-systemUptime)

        var didDeviceRebootSinceLastTime = false

        if let storedDateOfLastReboot:NSDate = userDefaults.objectForKey("deviceLastRebootDate") as? NSDate {

            if Int(dateOfLastReboot.timeIntervalSinceDate(storedDateOfLastReboot)) < 1 { //
                print("Reboot time didn't change - date: \(dateOfLastReboot)");
            }
            else {
                print("Reboot time has changed - from: \(storedDateOfLastReboot) to \(dateOfLastReboot)");
                didDeviceRebootSinceLastTime = true

            }
        }
        else {
            print("Reboot time is saved for the first time")
            didDeviceRebootSinceLastTime = true // first time we save value
        }

        userDefaults.setObject(dateOfLastReboot, forKey: "deviceLastRebootDate")
        userDefaults.synchronize() // don't forget this!!!

        return didDeviceRebootSinceLastTime;
    }

從iPhone或NIST獲取並保存時間,從BSD正常運行時間函數獲取當前運行時間。 對於NIST時間,請參閱如何在iPhone中獲取實時,而不是用戶在“設置”中設置的時間?

如果要檢查重新啟動,請獲取這些值的新值,計算每個值的經過時間並比較經過的時間。 根據差異,您應該能夠確定重新啟動。

這是我制作的。 它需要GMT中的當前時間和自上次重新引導以來的時間來推斷設備上次重新啟動的日期。 然后,它使用NSUserDefaults在內存中跟蹤此日期。 請享用!

注:由於要檢查這一點,因為最后一次的應用程序已經開始 ,你需要確保你調用的方法隨時應用程序已啟動。 最簡單的方法是在+(void)initialize {以及隨后在需要手動檢查時調用下面的方法

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM