我正在尝试设计一个发生实时事件的系统,并且我想将它们与时钟同步。 [NSDate date]
通常没问题,但用户可以更改此设置并欺骗系统。我所需要的只是一个可以从中获取相对时间的时钟(例如 64 位计数器)——我不需要绝对时间(或一天中的时间等)。
我可以使用这样的 API 吗?
编辑:我还想补充一点,这个时钟需要在应用程序的会话中保持不变。
我正在尝试设计一个发生实时事件的系统,并且我想将它们与时钟同步。 [NSDate date]
通常没问题,但用户可以更改此设置并欺骗系统。我所需要的只是一个可以从中获取相对时间的时钟(例如 64 位计数器)——我不需要绝对时间(或一天中的时间等)。
我可以使用这样的 API 吗?
编辑:我还想补充一点,这个时钟需要在应用程序的会话中保持不变。
iPhone 上最好的单调递增数字是mach_absolute_time()
自上次重启以来的 CPU 滴答计数。如果您出于任何原因想要在几秒钟内获得它,最容易使用CACurrentMediaTime()
.
使用它来创建“始终递增”非常容易。首次启动时,将当前值存储在您喜欢的任何位置。当您退出时,并定期保存该值的偏移量。重启时,检查当前值;如果它小于您以前的基本值,请替换您的基本值(已重新启动)。
当然,所有这些都可以通过删除你的应用程序来清除,除非你在服务器上存储了一些东西。
请注意,这不能用作强大的安全措施。没有办法阻止授权用户伪造请求。因此,取决于您所说的“欺骗系统”,这可能不是一个可解决的问题。您能做的最好的事情就是不断努力寻找黑客并与他们打交道。
如果您只需要一个时钟来测量单调递增的事件,您只需获取当前系统正常运行时间 ala 即可clock_gettime(CLOCK_MONOTONIC)
。如果重启设备有问题,只需保存上次使用的值,并在下次启动时使用上次保存的值作为偏移量。这里的问题可能是,如果他们真的关闭了设备,它就不会计算那个时间。但是,如果您担心用户会加快时间,他们就不能这样做,只能放慢速度。
我在我们的应用程序中使用它
+ (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/#qa/qa1398/_index.html
它基本上是自设备启动以来滴答数的计数器。这将在重新启动时重置,但除此之外它是一个单调递增的计数器。
如果计数器自上次(设备重新启动)以来减少,您可以保留计数器的最后一个值并处理它。在这种情况下,您可以将最后一个已知值添加到当前值以获得已过去时间的下限,您所失去的只是最后一次会话和设备关闭之间的时间,您将保持之间的时间重启和下一个会话。
据我所知,没有任何其他方法可以获得正确的时间。我会使用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
我能想到的唯一想法是使用 NTP 服务器来获取时钟,但这需要网络连接。