Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/111.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何知道NSURLSessionDataTask响应是否来自缓存?_Ios_Objective C_Caching_Nsurlsession_Cache Control - Fatal编程技术网

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