I have a file in my webserver and I am downloading that to my app everytime I access it because its possible that file content might be changed But If it is changed I would like to download that time only so bandwidth can be saved and fortunately that's what this ETag and If-None-Match header fields are for.
In the subsequent requests to download that file I'd attach the Etag value for If-None-Match headerfield so that if there is no change then I'd get HTTP response status code 304 or else I'd get 200 if there is a change in the file.
Note:
When I try the above steps in Advanced REST Client Application in chrome it works fine as it is supposed to be but when I try that in iOS I always get the response code 200 but it should have given me 304 for the subsequent requests.
Here is the sample code I use
var request1 = NSMutableURLRequest(URL:NSURL(string: "http://10.12.1.101/Etag/ringtone1.mp3")!)
let Etagvalue="\"36170-52c1cc36d9b40\""
var session1 = NSURLSession.sharedSession()
request1.HTTPMethod = "GET"
var err: NSError?
request1.addValue(Etagvalue, forHTTPHeaderField: "If-None-Match")
var task = session1.dataTaskWithRequest(request1, completionHandler: {data, response, error -> Void in
print("response: \(response)")
})
Here is the response
response: Optional( { URL: http://10.12.1.101/Etag/ringtone1.mp3 } { status code: 200, headers { "Accept-Ranges" = bytes; Connection = "Keep-Alive"; "Content-Length" = 221552; "Content-Type" = "audio/mpeg"; Date = "Wed, 24 Feb 2016 14:57:53 GMT"; Etag = "\"36170-52c1cc36d9b40\""; "Keep-Alive" = "timeout=5, max=100"; "Last-Modified" = "Fri, 19 Feb 2016 10:15:33 GMT"; Server = "Apache/2.4.16 (Unix) PHP/5.5.29"; } })
What am I doing wrong here ?
The If-None-Match HTTP request header makes the request conditional. For GET and HEAD methods, the server will return the requested resource, with a 200 status, only if it doesn't have an ETag matching the given ones.
An ETag (entity tag) is an HTTP header that is used to validate that the client (such as a mobile device) has the most recent version of a record. When a GET request is made, the ETag is returned as a response header. The ETag also allows the client to make conditional requests.
ETag supports strong and weak validation of the resource. Strong ETag indicates that resource content is same for response body and the response headers. Weak ETag indicates that the two representations are semantically equivalent.
I've encountered the same problem. I've discovered that it's because of cachePolicy
. You need to set it as follows:
request.cachePolicy = .ReloadIgnoringLocalAndRemoteCacheData
And you will be OK
CachePolicy naming convention is confusing and better yet it actually does not implement some of them...
This article explains them well. http://nshipster.com/nsurlcache/
Also, if you let the Cache Policy to use UseProtocolCachePolicy
then your NSURLSession will receive Status code 200
with response generated from Cache.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With