标签:显示 efault value 类型 and 失效 local alt request
在 iOS 开发中,凡是用到系统时间的,都要考虑一个问题:对时。有些业务是无需对时,或可以以用户时间为准的,比如动画用到的时间、一些日程类应用等。但电商相关的业务大都不能直接使用设备上的时间,而是需要跟服务器校准后的时间,例如:
可以看出,对时这个需求是非常普遍的。不过实现起来并不难,在这里分享一下我们的经验。
之所以叫解决方案,是因为这个功能不单是 app 端加几行代码,而是前后端配合完成的。大概思路如下:
服务器的时间戳可以加在 response body 里作为公共字段。在我的项目里,因为有少量 get 请求,所以放在了 response header 里。代码类似如下:
+ (void)handleSuccessResponse:(id)responseObject operation:(AFHTTPRequestOperation *)operation responseType:(Class)responseClass success:(void (^)(id))successBlock failure:(void (^)(NSError *))failureBlock {
long long timestamp = [[operation.response.allHeaderFields objectForKey:@"Response-Timestamp"] longLongValue];
[HAMDateTimeUtils updateServerTime:timestamp];
}
每次网络请求成功时更新时间差的缓存。
一个小的注意点是,处理 timestamp 最好始终用 long long 类型。因为 timestamp 传统上是以毫秒为单位的(虽然在 iOS 这个奇葩系统里 NSTimeInteval 是以秒为单位),在 32 位系统上 long 和 NSInteger 都存不下,会溢出。当然,现在 32 位系统的设备已经不常见了。
在更新缓存时,把服务器时间与本地当前的时间差保存在单例里。
- (void)updateServerTime:(long long)timestamp {
NSTimeInterval timeInteval = timestamp / 1000.0 - [[NSDate date] timeIntervalSince1970];
[self sharedInstance].timeIntevalDifference = timeInteval;
}
需要使用时间时,根据当前时间和缓存过的时间差,计算校准后的时间:
+ (NSDate*)currentTime {
NSDate* serverDate = [NSDate dateWithTimeIntervalSinceNow:[self sharedInstance].timeIntevalDifference];
return serverDate;
}
// 以毫秒为单位
+ (long long)currentTimeStamp {
NSTimeInterval localTime = [[NSDate date] timeIntervalSince1970];
NSTimeInterval timeDifference = [WNYDateTimeUtils sharedInstance].timeIntevalDifference;
return (long long)((localTimeStamp + timeDifference) * 1000);
}
使用时只需调用 [HAMDateTimeUtils currentTime]
或 [HAMDateTimeUtils currentTimeStamp]
即可。
Q:这样得出的时间准确吗?
A:会有一定误差。原因在于,服务器返回的时间戳是从服务器开始返回数据的时间,到客户端接收时会有一点延迟。不过对于我们的后台,这个延迟一般 <100 ms,对于我们的业务来说没什么影响。
如果对准确性要求更高,可以考虑使用专门的对时接口,不知道国家天文台有没有……
另外,这种对时的方案只是用于优化 UI 层面的显示,不能防止用户恶意的篡改。要始终记住客户端的时间戳是不可信的,后端业务凡是使用时间都务必用服务器的时间。
Q:缓存的时候,为什么只存在单例里,不持久化存储?
A:这个我也考虑过,主要是觉得再次启动的时候,时间差可能会发生变化,感觉持久化没有太大的必要。如果觉得有必要的话,也可以在 userDefault 里存一份,启动时取出来即可。
标签:显示 efault value 类型 and 失效 local alt request
原文地址:http://www.cnblogs.com/oc-bowen/p/6273726.html