ios-ntp 1.1.9

ios-ntp 1.1.9

测试已测试
语言语言 Obj-CObjective C
许可证 MIT
发布最后一次发布2018年6月

Gavin Eadie维护。



ios-ntp 1.1.9

  • Gavin Eadie

ios-ntp

一个网络时间协议客户端(以及iOS的应用程序测试平台)。这仍是一个持续的工作。

由Gavin Eadie于2010年10月17日创建

新闻

2018年6月4日:(版本1.1.9)在使用cocoasyncsocket和ios-ntp时出现冲突;添加了pod依赖项并从network-lib中删除了asyncsocket文件

2018年1月24日:(版本1.1.6)在几个方面进行了改进

  • 添加了tvOS的podspec目标。
  • CocoaAsyncSocket的文件替换为最新版本。

2016年12月20日:(版本1.1.4)在几个方面进行了改进

  • 强烈不建议使用pool ntp服务器主机名,因此已从此类代码和文档中删除。有关背景,请参阅NTP Pool Project页面:http://www.pool.ntp.org/vendors.html。注意:库在其新默认状态下将不查询任何服务器..现在必须提供ntp.hosts文件。

2016年2月1日:(版本1.1.3)在几个方面进行了改进

  • 对NTP 64位时间的算术运算略有改进。
  • NetAssocation的代理回调现在在主线程上运行,这允许它修改任何UI组件(从后台线程运行是非法的)。
  • 添加了一个“接收数据包过滤器”,但尚未调用。此将用于丢弃未通过验证的UPD包。
  • 现在[NetAssociation finish]将使计时器无效,因此关联不再参与时间推导。
  • 将源升级到最新的Objective-C约定。

快速时间检查

ios-ntp 通常(大多数情况下)用于确保没有人篡改系统时钟。在此目的下,使用多个服务器和平均时间偏移所带来的复杂性过多。下面的骨架代码就足以检查时间。如果想要更高的精度保证,可以重复操作几次;如果想要继续监控系统时间,可以每五分钟调用一次此代码。

	#import "ios-ntp.h"

	@interface ntpViewController : UIViewController <NetAssociationDelegate>

	@end

	@implementation ntpViewController
	- (void)viewDidLoad {
		[super viewDidLoad];

		netAssociation = [[NetAssociation alloc]
		initWithServerName:[NetAssociation ipAddrFromName:@"time.apple.com"]];
		netAssociation.delegate = self;
		[netAssociation sendTimeQuery];
	}

	- (void) reportFromDelegate {
		printf("time offset: %5.3f mSec", netAssociation.offset * 1000.0];
	}

2016年1月17日:(版本1.1.2)针对Xcode 7.x进行的小范围清理

2015年7月22日:(版本1.1.1)ios-ntp 包含一个资源文件(名为 ntp.hosts),其中包含时间服务器主机列表以供查询时间。在此版本中已移除该文件。

其逻辑是,由于 ios-ntp 可以通过 CocoaPods 添加到项目中,对那个文件的任何本地更改都将在下一次更新 ios-ntp pod 时被覆盖,并且由于 ios-ntp 已经包含内置的时间服务器列表,从 pod 中移除该文件不应影响 ios-ntp 代码的行为。

如果您想使用自己的时间服务器列表,您需要创建一个包含时间主机名的文件,每个主机名占一行,将其命名为 ntp.hosts 并放置在应用程序的主束中(示例应用程序 ios-ntp-app 通过这种方式使用 time.apple.com 服务器)。

2015年6月10日:(版本1.1)最近,当 John Grismore 让我注意到网络时间偏移量报告不精确时,我发现了一个可重入性错误。当一个 NetAssociation 通知 NetClock 它有一个新的时间偏移量时,该事件可能会中断 NetClock 进行的偏移量平均,从而导致平均中断。

实际上,这个机制本身就不太理想!引起偏移量平均的通知始终到达 NetClock,不管结果是否被使用。不管需要与否,我们都在保持 NetClock 网络时间偏移属性的最新状态。更好的做法是在需要时才进行平均,这正是 ios-ntp 的工作方式。

API 没有改变,所以您的应用程序不需要进行任何更改。

2015年2月22日:进行了一些重要更改,其中包括一个将有助于那些希望快速获得系统时间和网络时间差的开发者。

在此更改之前,ios-ntp 会使用一系列 NetAssociations(每个时间服务器一个)的时间估计值,不断通过采样这些值来确定最佳时间。这是针对具有持续低级别任务监控时间的计算机的模型。iOS 中的应用程序通常有不同的需求;它们更有可能需要按需快速估计时间。为此,提供了一种直接使用 NetAssociations 的功能,供开发者使用。

现在可以向个 NetAssociation 请求从单个时间服务器的时间度量,因此 iOS 应用程序可以创建一个 NetAssociation,使用它来获取时间,然后完成。

此代码适用于32位和64位iOS设备。

此代码 需要 iOS 7 或更高版本。


关于

最老款的 iPhone、iTouch 或 iPad 上的时钟与正确时间没有紧密同步。在从电话系统获取时间的设备的情况下,有一个设置可以启用以启用与电话公司时间的同步,但那种时间已知与正确时间相差一分钟以上。

此外,用户可能会修改他们的设备时间,这可能会严重影响依赖于正确时间来执行功能的应用程序,或者故意将设备时钟设置到过去,试图避开过期日期。

该项目包含使用简单网络时间协议(SNTP:RFC 5905)从标准时间服务器获取时间的代码。由于目标是提高时间精度到几十毫秒,而不是微秒,因此实现并不像该文档中描述的那样严格。

通常使用NTP协议的计算机通常将其用作连续的底层任务,以持续跟踪时间。一个后台应用程序使用来自一组时间服务器的偶尔时间估计来通过在时间上采样这些值以确定最佳时间。

ios-ntp提供了连续和按需操作模式。连续模式使用与时间服务器的多个“关联”,这些关联使用计时器反复获取时间估计。然而,开发者可以用这些关联从服务器获取单一的时间。

用法

可以将此代码作为源代码或框架集成到Xcode项目中。框架使用目前不可用,但很快将恢复。

有关使用框架的更多信息将随后提供。

下载ios-ntp项目,将其所需的元素添加到项目中,构建并运行。你需要

	#import "ios-ntp.h"

在引用ios-ntp的地方。

连续模式

简单地创建一个NetworkClock。创建它后,NTP进程将开始轮询“ntp.hosts”文件中的时间服务器。您可能希望在应用程序启动时启动它,以确保实际使用时时间已很好地同步,只需在AppDelegate的didFinishLaunching方法中调用即可。

	NetworkClock * nc = [NetworkClock sharedNetworkClock];

然后等待至少十秒,以便一些时间服务器发出响应,然后调用

	NSDate * nt = nc.networkTime;

大约需要一分钟,不信任的服务器才会开始从池中删除。

如果NetworkClock在有一个好时间时调用委托方法(如下面的NetAssociation那样),那可能更好,但现在它还不这样做,所以您必须等待事情稳定下来。

按需模式

这种使用方法稍微复杂一些。开发者必须创建一个NetAssociation(指定某些时间服务器),然后告诉它从这个服务器获取时间。关联使用委托方法返回自身带时间信息。

	netAssociation = [[NetAssociation alloc] initWithServerName:@"time.apple.com"];
	netAssociation.delegate = self;
	[netAssociation sendTimeQuery];

	...

	- (void) reportFromDelegate {
	   double timeOffset = netAssociation.offset;
	}

性能

iOS是一个以事件驱动为主,注重对手势快速响应的系统。为了提高响应速度,系统鼓励广泛使用像通知和代理这样的设计模式,因此我认为,在这个环境中端小的时差计算受到影响。

对一个时间服务器的一次观察表明,偶尔会出现比通常值大得多的时差;任何一个服务器的时差计算标准偏差,高于预期值,而我不知道这其中的原因。

许可

感谢MIT license批准。版权所有(c)2010-2018,Ramsay咨询。

历史

2014年11月19日:今天对ios-ntp进行了大量的更新,以使其适应现代世界。这些更改包括一个错误修复,但主要与使代码符合最近的Xcode更改和要求有关。

由于这些变化,以下jbenet的“用法”中的某些部分描述并不完全准确,我将很快更新文本。

请注意,此代码最初是在只有32位iOS设备时编写的。在我编写此代码时,仍然有一些32位设备运行最新的iOS版本(例如iPhone 4S),但是所有新的iOS设备都具有64位体系结构(例如iPhone 6),并且Apple需要支持这一点。