簡體   English   中英

如何知道 NSURLSessionDataTask 響應是否來自緩存?

[英]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。

更多信息: 關於 URLSessionTaskDelegate 的 Apple 文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM