Есть ли часы в iOS, которые могут быть использованы, которые не могут быть изменены пользователем
Я пытаюсь создать систему, в которой происходят события реального времени, и я хочу синхронизировать их с часами. [NSDate date]
обычно будет нормально, но пользователь может изменить это и обмануть систему. Все, что мне нужно, это часы, на которые я могу взять относительные времена (например, 64-разрядный счетчик) - мне не нужно абсолютное время (или время суток и т.д.).
Есть ли такой API, который я могу использовать?
EDIT: Я также хотел бы добавить, что эти часы должны быть постоянными в течение сеансов приложения.
Ответы
Ответ 1
Если все, что вам нужно, это часы для измерения событий как монотонно возрастающие, вы можете просто получить текущую работоспособность системы ala clock_gettime(CLOCK_MONOTONIC)
. Если перезагрузка устройства является проблемой, просто сохраните последнее значение, и при следующем запуске используйте последнее сохраненное значение в качестве смещения. Проблема здесь может заключаться в том, что если они фактически отключат устройство, это не будет считаться в то время. Но если вы беспокоитесь о том, что пользователь ускоряет время, они не могут этого сделать, только замедляют работу.
Ответ 2
Лучшим монотонно увеличивающимся номером на iPhone является mach_absolute_time()
, который является количеством тиков ЦП с момента последней перезагрузки. Если вы хотите использовать его в секундах по какой-либо причине, его легче всего получить с помощью CACurrentMediaTime()
.
Использование этого для создания "всегда-приращения" довольно просто. При первом запуске сохраните текущее значение везде, где захотите. Когда вы выходите и периодически сохраняете смещение от этого значения. При перезапуске проверьте текущее значение; если оно меньше вашего предыдущего базового значения, замените базовое значение (произошла перезагрузка).
Все это, конечно, можно очистить, удалив приложение, если вы не храните что-то на сервере.
Обратите внимание, что это нельзя использовать в качестве сильной меры безопасности. Невозможно предотвратить авторизацию авторизованного пользователя. Поэтому, в зависимости от того, что вы подразумеваете под "обманом системы", это не может быть решаемой проблемой. Лучшее, что вы можете сделать, это постоянное усердие, ищущее хаки и общение с ними.
Ответ 3
Я использую это в нашем приложении
+ (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;
}
Ответ 4
Я думаю, что mach_absolute_time()
может быть тем, что вы захотите. Здесь есть довольно много информации: http://developer.apple.com/library/mac/#qa/qa1398/_index.html
Это в основном счетчик количества тиков с момента запуска устройства. Это будет reset при перезагрузке, но кроме этого это монотонно увеличивающий счетчик.
Вы можете сохранить последнее значение счетчика и обработать его, если счетчик уменьшился с момента последнего (устройство было перезапущено). В этом случае вы можете добавить последнее известное значение к текущему значению, чтобы получить нижнюю границу времени, которое прошло, все, что вы потеряете, - это время между последним сеансом и выключением устройства, вы должны удерживать время между перезагрузка и следующий сеанс.
Ответ 5
Что я знаю, что нет другого способа получить правильное время. Я бы использовал NTP.
Протокол сетевого времени (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
Ответ 6
Единственная идея, о которой я могу думать, - использовать NTP-сервер для получения часов, но для этого потребуется подключение к сети.