iOS NSURLCache Last-modified Eta

2017-06-29  本文已影响320人  iOS104

缓存的目的:

NSURLCache

在iOS中,可以使用 NSURLCache 类缓存数据

NSURLCache *urlCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];
[NSURLCache setSharedURLCache:urlCache];

iOS对NSURLRequest提供了7种缓存策略

NSURLRequestUseProtocolCachePolicy // 默认的缓存策略(取决于协议)

NSURLRequestReloadIgnoringLocalCacheData // 忽略缓存,重新请求

NSURLRequestReloadIgnoringLocalAndRemoteCacheData // 未实现

NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData // 忽略缓存,重新请求

NSURLRequestReturnCacheDataElseLoad// 有缓存就用缓存,没有缓存就重新请求

NSURLRequestReturnCacheDataDontLoad// 有缓存就用缓存,没有缓存就不发请求,当做请求出错处理(用于离线模式)

NSURLRequestReloadRevalidatingCacheData // 未实现

控制缓存的有效性

如果本地缓存资源为最新,则使用使用本地缓存。如果服务器已经更新或本地无缓存则从服务器请求资源。

image.png
Last-modified

注:如果If-Modified-Since的时间比服务器当前时间(当前的请求时间request_time)还晚,会认为是个非法请求

- (void)getData:(GetDataCompletion)completion {
    NSURL *url = [NSURL URLWithString:kLastModifiedImageURL];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:15.0];

    // 发送 LastModified
    if (self.localLastModified.length > 0) {
        [request setValue:self.localLastModified forHTTPHeaderField:@"If-Modified-Since"];
    }

    [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

        
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
        NSLog(@"statusCode == %@", @(httpResponse.statusCode));
        // 判断响应的状态码是否是 304 Not Modified 
        if (httpResponse.statusCode == 304) {
            NSLog(@"加载本地缓存图片");
            // 如果是,使用本地缓存
            // 根据请求获取到`被缓存的响应`!
            NSCachedURLResponse *cacheResponse =  [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
            // 拿到缓存的数据
            data = cacheResponse.data;
        }
        // 获取并且纪录 LastModified
        self.localLastModified = httpResponse.allHeaderFields[@"Last-Modified"];
        
        NSLog(@"%@", self.localLastModified);
        dispatch_async(dispatch_get_main_queue(), ^{
            !completion ?: completion(data);
        });
    }] resume];
}
ETag

ETag是一个可以与Web资源关联的记号(token)。它是一个 hash 值,用作 Request 缓存请求头,每一个资源文件都对应一个唯一的 ETag 值, 服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端

更新原理:

Expires

max-age

Cache-Control中设置资源在本地缓存时间的一个值,单位为:秒(s),其他值还有private、no-cache、must-revalidate等

注意点:

控制缓存过期时间,无非两种:设置一个过期时间;校验缓存与服务端一致性,只在不一致时才更新。

一般情况下是不会对 api 层面做这种校验,只在有业务需求时才会考虑做,比如:

NSURLCache 解决不了的问题
上一篇 下一篇

猜你喜欢

热点阅读