码迷,mamicode.com
首页 > Web开发 > 详细

YTKNetwork系列之-----YTKRequest缓存ResponseData实现

时间:2015-07-07 00:52:52      阅读:2863      评论:0      收藏:0      [点我收藏+]

标签:

一、YTKRequest继承自YTKBaseRequest类,用于单独封装所有responseData缓存代码

// 首先YTKRequest的代码如下:

@interface YTKRequest : YTKBaseRequest

//表示当前请求,是否忽略本地缓存responseData
@property (nonatomic) BOOL ignoreCache;

/// 返回当前缓存的对象
- (id)cacheJson;

/// 是否当前的数据从缓存获得
- (BOOL)isDataFromCache;

/// 返回是否当前缓存需要更新【缓存是否超时】
- (BOOL)isCacheVersionExpired;

/// 强制更新缓存【不使用缓存数据】
- (void)startWithoutCache;

/// 手动将其他请求的JsonResponse写入该请求的缓存
- (void)saveJsonResponseToCacheFile:(id)jsonResponse;

/// 子类重写方法【参数方法】
- (NSInteger)cacheTimeInSeconds;    //当前请求指定时间内,使用缓存数据
- (long long)cacheVersion;    //当前请求,指定使用版本号的缓存数据
- (id)cacheSensitiveData;    

@end
    

  

二、然后从YTKRequest的start方法看起,这个方法表示开始执行请求

// 该方法的执行逻辑,如下:

- (void)start {

    //1. 当前请求,是否忽略缓存数据 
    if (self.ignoreCache) {
        [super start];
        return;
    }

    //2. 当前请求,是否设置了缓存超时时间
    if ([self cacheTimeInSeconds] < 0) {
        [super start];
        return;
    }

    //3. 当前请求,对应的本地缓存数据的版本号,是否与当前请求指定的版本号一致
    long long cacheVersionFileContent = [self cacheVersionFileContent];
    if (cacheVersionFileContent != [self cacheVersion]) {
        [super start];
        return;
    }

    //4. 当前请求,本地是否存在缓存数据文件
    NSString *path = [self cacheFilePath];
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:path isDirectory:nil]) {
        [super start];
        return;
    }

    //5. 当前请求,对应的缓存数据,是否已经超时
    int seconds = [self cacheFileDuration:path];
    if (seconds < 0 || seconds > [self cacheTimeInSeconds]) {
        [super start];
        return;
    }

    //6. 当前请求,对应的本地缓存数据文件,是否能够取到responseJSON
    _cacheJson = [NSKeyedUnarchiver     unarchiveObjectWithFile:path];
    if (_cacheJson == nil) {
        [super start];
        return;
    }

    //7. 如果以上情况,都不满足,表示本次请求的数据,来自本地缓存
    _dataFromCache = YES;
     
    //8. 结束本次请求,执行回调Block,释放Block
    [self requestCompleteFilter];

    YTKRequest *strongSelf = self;
    [strongSelf.delegate requestFinished:strongSelf];
    if (strongSelf.successCompletionBlock) {
        strongSelf.successCompletionBlock(strongSelf);
    }
    [strongSelf clearCompletionBlock];
}

 

三、本地缓存数据文件的管理方式:

管理方式一、按版本号

注意: 将一个responseJSON保存到本地,会同时产生2个文件
》文件一:保存responseData的文件
》文件二:标识本地保存responseData的版本号

//1. 得到responseJSON的缓存文件名

- (NSString *)cacheFileName {
    NSString *requestUrl = [self requestPath];
    NSString *baseUrl = nil;
    if ([self baseURLType] == ZSYBaseURLBasic) {
        baseUrl = [YTKNetworkConfig sharedInstance].basicBaseUrl;
    } else if ([self baseURLType] == ZSYBaseURLWealthManagement) {
        baseUrl = [YTKNetworkConfig sharedInstance].cashBaseUrl;
    }
    id argument = [self cacheFileNameFilterForRequestArgument:[self requestArgument]];
    NSString *requestInfo = [NSString stringWithFormat:@"Method:%ld Host:%@ Url:%@ Argument:%@ AppVersion:%@ Sensitive:%@",
                                                        (long)[self requestMethod], baseUrl, requestUrl,
                                                        argument, [YTKNetworkPrivate appVersionString], [self cacheSensitiveData]];
    NSString *cacheFileName = [YTKNetworkPrivate md5StringFromString:requestInfo];
    return cacheFileName;
}

//2. 2个缓存文件的全路径 
//文件一: 手机沙盒Document/LazyRequestCache/缓存文件名
//文件二: 手机沙盒Document/LazyRequestCache/缓存文件名.version

- (NSString *)cacheFilePath {
    NSString *cacheFileName = [self cacheFileName];
    NSString *path = [self cacheBasePath];
    path = [path stringByAppendingPathComponent:cacheFileName];
    return path;
}

//3. 读取版本号文件中保存的NSNumber值

- (long long)cacheVersionFileContent {
    NSString *path = [self cacheVersionFilePath];
    NSFileManager * fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:path isDirectory:nil]) {
        NSNumber *version = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
        return [version longLongValue];
    } else {
        return 0;//默认版本号=0
    }
}

//4. 当前请求指定的版本号 与 本地缓存文件保存的版本号 ,对比后如果一致表示是合法缓存数据,否则是不合法缓存数据

long long cacheVersionFileContent = [self cacheVersionFileContent];
    if (cacheVersionFileContent != [self cacheVersion]) {
        [super start];
        return;
    }

//5. 保存从服务器获取到的responseJSON按版本号

- (void)saveJsonResponseToCacheFile:(id)jsonResponse {

    //1. 当前请求设置过缓存超时--》使用缓存
    //2. responseJSON不是来自本地缓存文件
    if ([self cacheTimeInSeconds] > 0 && ![self isDataFromCache]) {
        NSDictionary *json = jsonResponse;
        if (json != nil) {

            //保存responseJSON
            [NSKeyedArchiver archiveRootObject:json toFile:[self cacheFilePath]];

            //保存当前request指定的版本号
            [NSKeyedArchiver archiveRootObject:@([self cacheVersion]) toFile:[self cacheVersionFilePath]];
        }
    }
}

 

管理方式二、按超时时间

/**
 *
 * 核心:
 *      通过本地文件,创建时间 与 当前操作时间,的时间差,是否超过指定的时间长度
 *
 */

- (int)cacheFileDuration:(NSString *)path {
    NSFileManager *fileManager = [NSFileManager defaultManager];
    // get file attribute
    NSError *attributesRetrievalError = nil;
    NSDictionary *attributes = [fileManager attributesOfItemAtPath:path
                                                             error:&attributesRetrievalError];
    if (!attributes) {
        YTKLog(@"Error get attributes for file at %@: %@", path, attributesRetrievalError);
        return -1;
    }
    int seconds = -[[attributes fileModificationDate] timeIntervalSinceNow];
    return seconds;
}


int seconds = [self cacheFileDuration:path];
    if (seconds < 0 || seconds > [self cacheTimeInSeconds]) {
        [super start];
        return;
    }

 

YTKNetwork系列之-----YTKRequest缓存ResponseData实现

标签:

原文地址:http://www.cnblogs.com/xiongzenghui/p/4625672.html

(0)
(1)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!