如果处理服务器与客户端时间不一致的问题

来源:互联网 发布:linux安装windows软件 编辑:程序博客网 时间:2024/05/17 03:19
  1. 前一段时间做了一个倒计时的功能,要求每个tableViewcell里面都嵌入倒计时的功能。我也封装了一个工具类,详细请看这里
  2. 但是倒计时如果不是用服务器的现在时间进行剩余时间计算的话,就可能出现bug(比如一个商品,倒计时1小时停售,服务器已经过了这停售时间,从而停售了,但是客户端的时间比服务器时间向后调了1小时,那么客户端就会以为还没有停售)
  3. 这就要求要用客户端的时间求出服务器的时间

1、大体思路

其实很简单就说一下大体的思路,在附一个小的工具类,很简单。。。
1. 封装一个类,在请求到后台的时间戳后,把本地时间与后台时间戳进行对比,记录时间差,最后每次时间计算的时候,都可以用本地时间求出服务器的时间。
2. 关键是什么时候请求服务器时间。
1.我们先分析一下,首先,这种时间差,越早知道越好,所以,在app启动的时候就要请求服务器时间,并计算差值。

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {}    app刚刚启动的时候创建并给出serverTime,内部计算了服务器时间

2.假设,用户很调皮,在app运行后,就退出去,对手机的时间设置成一个随意时间。那再进来,再用以前储存的时间差计算服务器时间,岂不是炸了。
所以在app进入后台、应用程序编程不激活状态、从后台进入到前台等都要调用一下,一下代码满足了这些时机的需求

-(void)applicationWillResignActive:(UIApplication *)application {}    应用程序变成不激活状态,双击home建,应用程序不在相应用户点击的时候-(void)applicationDidEnterBackground:(UIApplication *)application{}    应用程序进入到后台的时候调用,双击home建不会调用-(void)applicationWillEnterForeground:(UIApplication *)application{}    应用程序从后台进入到前台以后调用这个方法, 应用启动不会调用-(void)applicationDidBecomeActive:(UIApplication *)application{}    应用程序变为激活状态的时候会调用这个方法,(用户可以进行用户交互的时候调用)-(void)applicationWillTerminate:(UIApplication *)application{}    系统将要推出(终止)的时候调用

2. 代码剪辑
.h

#import <Foundation/Foundation.h>@interface PYServerAndClientTime : NSObject///单利+ (instancetype) sharedServerAndClientTime;///内部创建了sharedServerAndClientTime对象+ (instancetype) serVerAndClientTimeWithServerTime: (NSString *)serverTime;///服务器的时间戳@property (nonatomic,copy) NSString *serverTime;///计算后的服务器时间@property (nonatomic,strong,readonly) NSDate *serverAndClientDate;///计算后服务器时间的timeInterval@property (nonatomic,assign,readonly) NSNumber *serverAndClientTimeInterval;///服务器与客户端时间的时间差@property (nonatomic,assign,readonly) NSNumber *timeDifference;@end

.m

@implementation PYServerAndClientTime+ (instancetype) sharedServerAndClientTime {    static dispatch_once_t onceToken;    static PYServerAndClientTime *_instance;    dispatch_once(&onceToken, ^{        _instance = [[self alloc]init];    });    return _instance;}+(instancetype) serVerAndClientTimeWithServerTime: (NSString *)serverTime {    PYServerAndClientTime *serverAndClientTime = [PYServerAndClientTime sharedServerAndClientTime];    serverAndClientTime.serverTime = serverTime;    return serverAndClientTime;}//MARK: setter-(void)setServerTime:(NSString *)serverTime {    _serverTime = serverTime;   double serverTimeDouble = serverTime.longLongValue;    //计算当前的时间秒数    NSTimeInterval currentDateInterval = [[[NSDate alloc]init] timeIntervalSince1970];    //计算时差     NSNumber *timeDifferenceTemp = @(serverTimeDouble - currentDateInterval);    [self setValue:timeDifferenceTemp forKey:@"timeDifference"];}//MARK: getter-(NSDate *)serverAndClientDate {    return [NSDate dateWithTimeIntervalSinceNow:self.timeDifference.doubleValue];;}-(NSNumber *)serverAndClientTimeInterval {    return @([self.serverAndClientDate timeIntervalSince1970]);}@end

appDelegate

#import "AppDelegate.h"#import "PYServerAndClientTime.h"@interface AppDelegate ()@end@implementation AppDelegate//根据服务器时间计算与本地时间的时间差-(void)serverAndClientTime {    /**......     服务器请求数据     .......     */    NSString *serverTime;//服务器求情下来之后的服务器时间戳    PYServerAndClientTime *serverAndClientTime = [PYServerAndClientTime sharedServerAndClientTime];    serverAndClientTime.serverTime = serverTime;}-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    //app刚刚启动的时候创建并给出serverTime,内部计算了服务器时间    [self serverAndClientTime];    return YES;}-(void)applicationWillResignActive:(UIApplication *)application {    // 应用程序变成不激活状态,双击home建,应用程序不在相应用户点击的时候    [self serverAndClientTime];}-(void)applicationDidEnterBackground:(UIApplication *)application {    //应用程序进入到后台的时候调用,双击home建不会调用  [self serverAndClientTime];}-(void)applicationWillEnterForeground:(UIApplication *)application {    //应用程序从后台进入到前台以后调用这个方法, 应用启动不会调用  [self serverAndClientTime];}-(void)applicationDidBecomeActive:(UIApplication *)application {    //应用程序变为激活状态的时候会调用这个方法,(用户可以进行用户交互的时候调用)   [self serverAndClientTime];}-(void)applicationWillTerminate:(UIApplication *)application {   //系统将要推出(终止)的时候调用}@end
阅读全文
1 0
原创粉丝点击