Есть ли в 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-сервер для получения часов, но для этого потребуется подключение к сети.