当transfer-encoding的响应头值被分块时,NSURLCache不起作用

时间:2015-03-18 01:52:45

标签: ios swift caching ios8 nsurlcache

我在查看Charles Proxy中的请求和响应标头时发现了(可能)NSURLCache的问题。这个问题有点令人困惑,但我能够始终如一地重复它:

简而言之,问题与使用iOS的本地NSURLRequest使用默认策略缓存NSURLCache s有关。事实证明,只要响应具有标头transfer-encoding: chunked,就不会缓存请求。但是如果响应标头是content-length: xxx,则缓存可以正常工作。具体来说,似乎当响应被分块时,NSURLCache不会保存eTag并且忽略将if-none-match标头附加到对同一URL的后续请求,因此,缓存失败(应该如此),即返回200而不是304.

我在iOS8.2模拟器上进行测试。即使你没有解决方案,我也很乐意听到你是否经历过同样的问题。我至少找到了one similar report),而且这里是related thread posted by my back-end engineer

1 个答案:

答案 0 :(得分:1)

如果您手动将响应数据添加到缓存,它应该可以工作。我有一个图像加载类,我想确保所有内容都被缓存,所以我做这样的事情:

- (void)getImageWithURL:(NSURL *)url onCompletion:(void (^)(UIImage *image, NSError *error))completion {
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    UIImage *cachedImage = [self cachedImageForURLRequest:request];
    if (cachedImage) {
        NSLog(@"Got image from cache.");
        completion(cachedImage, nil);
        return;
    }

    [[[NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        // Manually cache the response.
        NSCachedURLResponse *cachedResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:data userInfo:nil storagePolicy:NSURLCacheStorageAllowed];
        [[NSURLCache sharedURLCache] storeCachedResponse:cachedResponse forRequest:request];
        NSLog(@"Got a fresh image.");
        completion([UIImage imageWithData:data], error);
    }] resume];
}

- (UIImage *)cachedImageForURLRequest:(NSURLRequest *)urlRequest {
    NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:urlRequest];
    return [UIImage imageWithData:cachedResponse.data];
}