Ios 如何知道NSURLSessionDataTask响应是否来自缓存?
我想确定来自Ios 如何知道NSURLSessionDataTask响应是否来自缓存?,ios,objective-c,caching,nsurlsession,cache-control,Ios,Objective C,Caching,Nsurlsession,Cache Control,我想确定来自NSURLSessionDataTask的响应是来自缓存还是来自服务器 我正在从创建我的NSURLSessionDataTask request.cachePolicy = NSURLRequestUseProtocolCachePolicy; 我想到了两个简单的选择: 在发出请求之前,请调用[[NSURLCache sharedullcache]cachedResponseForRequest:request],存储缓存的响应,然后在接收完数据后再次执行此操作,并比较两个缓存的
NSURLSessionDataTask
的响应是来自缓存还是来自服务器
我正在从创建我的NSURLSessionDataTask
request.cachePolicy = NSURLRequestUseProtocolCachePolicy;
我想到了两个简单的选择:
- 在发出请求之前,请调用
,存储缓存的响应,然后在接收完数据后再次执行此操作,并比较两个缓存的响应以查看它们是否相同[[NSURLCache sharedullcache]cachedResponseForRequest:request]
- 使用
缓存策略发出初始请求,如果失败,则使用更合理的策略发出第二个请求NSURLRequestReturnCacheDataDontLoad
第一种方法通常更可取,因为第二种方法将返回缓存中存在的数据,即使数据已过时。但是,在一些罕见的情况下(例如脱机模式),这可能是您想要的,这就是我提到它的原因。如果您的信息需求只是出于好奇,您可以查看您的网络使用情况Xcode runtime network metics。将策略更改为其他设置并观察差异 如果要使用缓存,那么在客户端上禁用缓存不是一个好办法 如果服务器设置了缓存头(etag,cache control=“no store”),那么NSURLSession将重新验证并根据服务器的200/304响应为您提供缓存/刷新响应。但是,在代码中,无论NSUrlSession接收到的是200还是304,您都将始终看到状态代码200。这是有限的,因为当响应没有改变时,您可能希望跳过解析、重新创建对象等 我所做的变通方法是在响应中使用etag值来确定是否有更改
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse *)response;
NSString *etag = (httpResp && [httpResp isKindOfClass:[NSHTTPURLResponse class]]) ? httpResp.allHeaderFields[@"Etag"] : nil;
BOOL somethingHasChanged = [etag isEqualToString:oldEtag];
为了知道URLSessionDataTask响应是来自缓存还是来自网络,您必须使用自定义URLSession,并为其提供
URLSessionTaskDeleteGate
,它必须实现以下方法:
func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics)
您将在度量
中找到非常有用的信息,特别是请求的事务度量列表。每个事务度量都有一个属性resourceFetchType
,可以是.localCache、.networklLoad、.serverPush或.unknown
此处的更多信息:如何比较两个缓存响应?
大概相等。您从哪里获得oldEtag
?