Есть ли в iOS часы, которые не могут быть изменены пользователем

Я пытаюсь спроектировать систему, в которой происходят события в реальном времени, и я хочу синхронизировать их с часами. [NSDate date] было бы нормально, но пользователь мог изменить это и обмануть систему. Все, что мне нужно, это часы, из которых я могу взять относительное время (например, 64-битный счетчик) - мне не нужно абсолютное время (или время суток и т. Д.).

Есть ли такой API, который я могу использовать?

РЕДАКТИРОВАТЬ: Я также хотел бы добавить, что эти часы должны быть постоянными в течение сеансов приложения.

6 ответов

Решение

Если все, что вам нужно, это часы для измерения событий как монотонно возрастающих, вы можете просто получить текущее время работы системы. clock_gettime(CLOCK_MONOTONIC), Если перезапуск устройства является проблемой, просто сохраните последнее использованное значение и при следующем запуске используйте последнее сохраненное значение в качестве смещения. Проблема здесь может заключаться в том, что если они действительно отключат устройство, оно не будет считать это время. Но если вы беспокоитесь о том, что пользователь ускоряет время, он не может этого сделать, только замедляет его.

Лучший монотонно увеличивающийся номер на iPhone mach_absolute_time() это число тактов процессора с момента последней перезагрузки. Если по какой-либо причине вы хотели бы получить его за считанные секунды, его легче всего получить с CACurrentMediaTime(),

Использовать это для создания "всегда инкремента" довольно легко. При первом запуске сохраните текущее значение, где хотите. При выходе и периодически сохраняйте смещение от этого значения. При перезапуске проверьте текущее значение; если оно меньше вашего предыдущего базового значения, замените его базовым значением (произошла перезагрузка).

Все это, конечно, можно очистить, удалив ваше приложение, если вы не храните что-либо на сервере.

Обратите внимание, что это не может быть использовано в качестве строгой меры безопасности. Не существует способа помешать авторизованному пользователю подделывать запросы. Поэтому, в зависимости от того, что вы подразумеваете под "обманом системы", это может быть не решаемой проблемой. Лучшее, что вы можете сделать, - это постоянно усердно искать хаки и иметь с ними дело.

Я использую это в нашем приложении

+ (NSDate *) getAWSDate
{
    NSDate *today = nil; 
   NSString *dateString = nil;

    NSString *awsURL = @"http://s3.amazonaws.com";
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:awsURL]];  
    [request setHTTPMethod:@"HEAD"];  

    NSHTTPURLResponse *response;  
    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error: NULL];  

    if ([response respondsToSelector:@selector(allHeaderFields)]) {  
        dateString = [[response allHeaderFields] objectForKey:@"Date"];
        dateString = [dateString stringByReplacingOccurrencesOfString:@"GMT" withString:@"+0000"];
        NSDateFormatter *df = [[NSDateFormatter alloc] init];  
    df.dateFormat = @"EEE, dd MMM yyyy HH:mm:ss z";
    df.locale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease];  
    df.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];  
    today = [df dateFromString:dateString];
    [df release];    
    }           
    return today;
}

Я думаю mach_absolute_time() может быть то, что вы хотите. Здесь довольно много информации: http://developer.apple.com/library/mac/

Это в основном счетчик количества тиков с момента запуска устройства. Это будет сброшено при перезагрузке, но это монотонно увеличивающийся счетчик.

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

Что я знаю, что нет другого способа получить правильное время. Я бы использовал NTP.

Network Time Protocol (NTP) - это сетевой протокол для синхронизации часов компьютерных систем по сетям передачи данных с переменной задержкой и коммутацией пакетов. Подробнее: http://en.wikipedia.org/wiki/Network_Time_Protocol

В одном проекте я собираюсь использовать NTP (завтра я угадаю), но я уже провел некоторые исследования:

Библиотека iOS: https://github.com/jbenet/ios-ntp - Автор отмечает: Реализация не является строгой, как описано в этих RFC, поскольку цель состояла в том, чтобы повысить точность времени с точностью до секунды, а не до долей миллисекунд,

Для некоммерческого проекта смотрите: www.packages.ubuntu.com/source/lucid/ntp

Библиотека C: www.hillstone-software.com/hs_ntp_details.htm

Документация: www.nist.gov/pml/div688/grp40/its.cfm

Единственная идея, о которой я могу подумать, - это использовать NTP-сервер для получения часов, но для этого потребуется подключение к сети.

Другие вопросы по тегам