[英]How to know if NSURLSessionDataTask response came from cache?
我想確定來自NSURLSessionDataTask
的響應是來自緩存還是來自服務器
我NSURLSessionDataTask
創建我的NSURLSessionDataTask
request.cachePolicy = NSURLRequestUseProtocolCachePolicy;
想到兩個簡單的選擇:
[[NSURLCache sharedURLCache] cachedResponseForRequest:request]
之前調用[[NSURLCache sharedURLCache] cachedResponseForRequest:request]
,存儲緩存的響應,然后在接收數據后再次執行此操作,並比較兩個緩存的響應以查看它們是否相同。NSURLRequestReturnCacheDataDontLoad
緩存策略發出初始請求,如果失敗,則使用更合理的策略發出第二個請求。第一種方法通常更可取,因為第二種方法將返回緩存中存在的數據,即使它是陳舊的。 但是,在某些極少數情況下(例如離線模式),這可能正是您想要的,這就是我提到它的原因。
如果您的信息需求只是出於好奇,您可以查看您的網絡使用情況 Xcode 運行時網絡指標。 將策略更改為不同的設置並觀察差異。
如果您想使用緩存,那么在客戶端上禁用緩存不是一個好的答案。
如果服務器設置了緩存標頭(etag,cache-control="no-store"),那么 NSURLSession 將重新驗證並根據來自服務器的 200 / 304 響應為您提供緩存/新鮮響應。 但是,在您的代碼中,無論 NSUrlSession 收到 200 還是 304,您始終會看到 statusCode 200。這是限制性的,因為您可能希望在響應未更改時跳過解析、重新創建對象等。
我所做的解決方法是使用響應中的 etag 值來確定某些內容是否已更改
NSHTTPURLResponse *httpResp = (NSHTTPURLResponse *)response;
NSString *etag = (httpResp && [httpResp isKindOfClass:[NSHTTPURLResponse class]]) ? httpResp.allHeaderFields[@"Etag"] : nil;
BOOL somethingHasChanged = [etag isEqualToString:oldEtag];
為了知道 URLSessionDataTask 響應是來自緩存還是來自網絡,您必須使用自定義 URLSession 並為其提供URLSessionTaskDelegate
,該URLSessionTaskDelegate
必須實現以下方法:
func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics)
您會在metrics
找到非常有用的信息,尤其是請求的交易指標列表。 每個事務指標都有一個屬性resourceFetchType
,它可以是 .localCache、.networklLoad、.serverPush 或 .unknown。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.