Если есть способ обнаружить, что устройство iPhone было перезагружено, когда приложение находится в фоновом режиме [дубликат]

Интересно, что ни один из ответов на этой странице не упоминает два крайних случая, надеюсь, никто не возражает, если я их добавлю:

Случай с краем # 1: одновременный доступ к словарю

Родовые словари в .NET не являются потокобезопасными, а иногда могут бросать NullReference или даже (чаще) a KeyNotFoundException при попытке получить доступ к ключу из двух параллельных потоков. Исключение в этом случае является довольно ошибочным.

Случай с краем # 2: небезопасный код

Если код NullReferenceException задан кодом unsafe, вы можете посмотреть на переменные указателя , и проверьте их на IntPtr.Zero или что-то в этом роде. Это одно и то же («исключение нулевого указателя»), но в небезопасном коде переменные часто переводятся в типы значений / массивы и т. Д., И вы ударяете головой о стену, задаваясь вопросом, как тип значения может исключение.

(Еще одна причина для небезопасного использования небезопасного кода, если вам это нужно)

5
задан Maxm007 18 September 2009 в 11:04
поделиться

5 ответов

Кажется, что это сработает:

  • получить время с момента последней перезагрузки, и для этого примера давайте сохраним его в переменной под названием «tslr» (продолжительность в миллисекундах, я думаю, BTW , как вы это получите?)
  • получить текущее время, сохранить его в переменной 'ct', например
  • вычислить последнее время перезагрузки (назовем его 'lr'), мы имеем: lr = ct - tslr
  • store 'lr'

При следующем запуске приложения загрузите предыдущее значение для 'lr', вычислите новый , и если они будут отличаться, вы обнаружите перезагрузку (вам, вероятно, придется терпеть небольшую разницу ... возможно, пару миллисекунд).

Я думаю, было бы довольно сложно обмануть это. .. пользователь должен был бы точно изменить время своего телефона, и они должны были бы начать ваше приложение в очень точный момент поверх этого, точно, когда новый «lr» был бы идентичен предыдущему ... pretty трудно сделать, вероятность того, что они могут это сделать, очень близка к 0 I th чернила. И вам не нужно какое-либо интернет-соединение, чтобы это сделать ...

Новый «lr» был бы идентичен предыдущему в следующих случаях:

  • телефон не был перезагружен, а время не было изменено.
  • Время
  • было изменено. И пользователю удалось запустить ваше приложение на точной миллисекунде, чтобы обмануть ваш алгоритм (вероятность того, что это происходит более, чем ультрасимметрично)
10
ответ дан Zoran Simic 4 September 2018 в 08:47
поделиться
  • 1
    Brilliant. Работает отлично и в то же время обнаруживает, что пользователь меняет дату iphone. Теперь я могу аннулировать любое время, когда пользователь забил, который был изменен без сетевого подключения. Btw: вы можете получить время с момента перезагрузки с помощью таймера mach: discussion.apple.com/thread.jspa?threadID=1632831 – Maxm007 19 September 2009 в 22:37
  • 2
    Хм, этот таймер машины странный. Несмотря на то, что мой iphone был на всю ночь и не перезагружался, таймер, похоже, перезагрузился. – Maxm007 20 September 2009 в 11:05
  • 3
    Этот метод кажется надежным способом обеспечения работоспособности системы без использования частных API или системных вызовов: developer.apple.com/library/mac/documentation/Cocoa/Reference/… – Sean Dawson 7 April 2015 в 04:52
  • 4
    Фактически [[NSProcessInfo processInfo] systemUptime] не работает для этой цели из-за: stackoverflow.com/questions/6052206/frozen-uptime-on-ios-iphone . CACurrentMediaTime () - лучший выбор. – Sean Dawson 7 April 2015 в 06:53
  • 5
    Но если «lr» не идентичен предыдущему, как я могу сказать, что это связано с перезагрузкой (обычный способ использования приложения) или они нарушили системное время (ненормальный способ использования приложения)? – Code Farmer 29 September 2017 в 01:34

Вот один, который я сделал. Он занимает текущее время в 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;
}
0
ответ дан Albert Renshaw 4 September 2018 в 08:47
поделиться

Получите и сохраните время либо с iPhone, либо с NIST и текущего времени исполнения из функции повышения производительности BSD. Для времени NIST см. Как я могу получить реальное время в iPhone, а не время, заданное пользователем в настройках?

Когда вы хотите проверить перезагрузку, получите новые значения этих , вычислить прошедшее время для каждого и сравнить прошедшее время. Исходя из разницы, вы должны иметь возможность определить перезагрузку.

0
ответ дан Community 4 September 2018 в 08:47
поделиться
  • 1
    В моем случае это не сработает, потому что я не могу зависеть от интернет-соединения и не могу зависеть от времени iPhone, потому что это может быть подделано пользователем. – Maxm007 18 September 2009 в 14:10
  • 2
    Пользователь также может вмешиваться в ваше приложение. Насколько вам это безопасно? – Amok 18 September 2009 в 20:11
  • 3
    Пользователь не может легко манипулировать моим приложением, потому что он имеет цифровую подпись. Он определенно должен быть более безопасным, чем изменение времени iPhone в настройках - & gt; Общее - & gt; Время – Maxm007 18 September 2009 в 22:26
    // 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;
    }
2
ответ дан Oded Regev 4 September 2018 в 08:47
поделиться

Ответ Зорана - правильный путь; это самое близкое, что вы получите без сетевого подключения. (ни мобильная подсистема, ни системный журнал не доступны по соображениям безопасности).

Если вы хотите предотвратить появление вредоносных данных от вредоносных пользователей, обратитесь к треку центрального сервера (или доверенного локального сервера для развертывания предприятия) связанные с временем события.

1
ответ дан rpetrich 4 September 2018 в 08:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: