NSURLCache无视最大年龄

时间:2015-11-09 02:08:51

标签: ios objective-c nsurlsession cache-control nsurlcache

我使用以下代码从TfL下载一些数据。

NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
                                                      delegate:self delegateQueue:[NSOperationQueue mainQueue]];

NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://api.tfl.gov.uk/StopPoint/490012211N/Arrivals"]];

[[session dataTaskWithRequest:req
        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            if (!error) {
                NSLog(@"Loaded Succesfully");
            }
            NSCachedURLResponse *resp = [[NSURLCache sharedURLCache] cachedResponseForRequest:req];
            if (resp) {
                NSLog(@"Response in cache");
            }
            [[session dataTaskWithRequest:req
                        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                            if (!error) {
                                NSLog(@"Loaded Sucessfully again");
                            }
                        }] resume];
        }] resume];

响应的缓存控制头字段为public, must-revalidate, max-age=5, s-maxage=10这似乎意味着即使第二个请求在max-age给出的5秒内,服务器也会发送请求。如果我使用Charles编辑响应并删除必须重新生效,那么上面的代码只会向服务器发送一次请求。

HTTP / 1.1规范说

  

该缓存在变为陈旧以响应a之后不得使用该条目   后续请求,而不首先使用原始服务器重新验证它。

对于must-revalidate,但似乎iOS似乎忽略了"它变得陈旧"部分?并将must-revalidate表示忽略max-age。那么如何将字段设置为根本不缓存呢?我已经检查过并且请求/响应正被添加到缓存中,所以看起来must-revalidate只是膨胀缓存,因为它不会使用它,但仍然将它添加到缓存中?

服务器错误地将must-revalidatemax-age结合使用,或者iOS处理must-revalidate的方式不正确吗?

有没有办法拦截回复,以便我可以删除must-revalidate? NSURLProtocol似乎有用,但我只能看到如何修改请求,而不是响应。

1 个答案:

答案 0 :(得分:0)

如果你使用NSURLProtocol,你可以发出一个新请求(确保标记它以便你不会再次修改它),然后在响应上,你可以创建一个新的响应对象,基于旧的,并将修改后的响应发送给客户端。这是否足以解决您的问题,我不确定。

然而,更好(阅读"更直接实现")解决方案可能是子类化NSURLCache对象并使用您的自定义子类作为共享缓存(对于NSURLConnection和NSURLSession共享会话)或作为每会话缓存(对于其他NSURLSession会话)。