Reputation: 1031
Does NSURLCache
transparently handle ETags received by server?
I mean: does it automatically store ETags for each URL request and then send the appropriate If-None-Match
when a request to the same URL is submitted?
Or do I have to manage it by myself?
Upvotes: 17
Views: 9636
Reputation: 9505
For posterity, this is how to use ETag with swift:
let API_HEADER_FIELD_NONE_MATCH = "If-None-Match"
let API_HEADER_FIELD_ETAG = "Etag"
let API_REQUEST_SUCCESS : Int = 200
let API_REQUEST_NOT_MODIFIED : Int = 304
//inject ETag
let config = URLSessionConfiguration.default
config.httpAdditionalHeaders = [API_HEADER_FIELD_NONE_MATCH: storedEtag]
config.requestCachePolicy = .reloadIgnoringLocalAndRemoteCacheData
let urlSession = URLSession(configuration: config)
let (jsonData, response) = try await urlSession.data(from: dataURL)
guard let httpResponse = response as? HTTPURLResponse else {
throw some error
}
switch httpResponse.statusCode {
case API_REQUEST_SUCCESS:
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
if let responseETag = httpResponse.allHeaderFields[API_HEADER_FIELD_ETAG] as? String {
let decodedData = try decoder.decode(TrackerData.self, from: jsonData)
return (decodedData, responseETag)
} else {
throw some error "Missing ETag"
}
case API_REQUEST_NOT_MODIFIED:
//the data represented by the stored etag is up to date
default:
throw APIError.apiError(reason: "Unexpected HTTP response code \(httpResponse.statusCode)")
}
Upvotes: 0
Reputation: 50109
yes it does handle it transparently if you set its cache mode:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]
cachePolicy: NSURLRequestUseProtocolCachePolicy
timeoutInterval:60];
note: you cannot see the header in the request at all and if a 304 response is returned by the server you will only see the 200 response that it transparently loaded from the cache.
Upvotes: 23