How to Disable Caching in Alamofire

How to disable caching in Alamofire

swift 3, alamofire 4

My solution was:

creating extension for Alamofire:

extension Alamofire.SessionManager{
@discardableResult
open func requestWithoutCache(
_ url: URLConvertible,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
encoding: ParameterEncoding = URLEncoding.default,
headers: HTTPHeaders? = nil)// also you can add URLRequest.CachePolicy here as parameter
-> DataRequest
{
do {
var urlRequest = try URLRequest(url: url, method: method, headers: headers)
urlRequest.cachePolicy = .reloadIgnoringCacheData // <<== Cache disabled
let encodedURLRequest = try encoding.encode(urlRequest, with: parameters)
return request(encodedURLRequest)
} catch {
// TODO: find a better way to handle error
print(error)
return request(URLRequest(url: URL(string: "http://example.com/wrong_request")!))
}
}
}

and using it:

Alamofire.SessionManager.default
.requestWithoutCache("https://google.com/").response { response in
print("Request: \(response.request)")
print("Response: \(response.response)")
print("Error: \(response.error)")
}

Alamofire unable disable caching

This is working:

URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)

And then just Alamofire.request

How to disable the URLCache completely with Alamofire

Why are you not configuring the session? If you configure the session correctly, there will be no caching.

Example:

//Create a non-caching configuration.
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
config.requestCachePolicy = .ReloadIgnoringLocalAndRemoteCacheData
config.URLCache = nil

//Allow cookies if needed.
config.HTTPCookieStorage = NSHTTPCookieStorage.sharedHTTPCookieStorage()


//Create a manager with the non-caching configuration that you created above.
self.manager = Alamofire.Manager(configuration: config)


//Examples of making a request using the manager you created:

//Regular HTML GET request:
self.manager.request(.GET, "https://stackoverflow.com")
.validate(statusCode: 200..<300)
.validate(contentType: ["text/html"])
.responseString { (response) in
guard response.result.isSuccess else {
print("Error: \(response.result.error)")
return
}
print("Result: \(response.result.value)")
}


//JSON GET request:
self.manager.request(.GET, "someURL", parameters: params, encoding: .URL, headers: headers)
.validate(statusCode: 200..<300)
.validate(contentType: ["application/json"])
.responseJSON { (response) in
guard response.result.isSuccess else {
print("Error: \(response.result.error)")
return
}

print(response.result.value as? [String: AnyObject])
}

Edit:

let manager = {() -> Alamofire.Manager in
struct Static {
static var dispatchOnceToken: dispatch_once_t = 0
static var instance: Alamofire.Manager!
}

dispatch_once(&Static.dispatchOnceToken) {
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
config.requestCachePolicy = .ReloadIgnoringLocalAndRemoteCacheData
config.URLCache = nil

let cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage()
config.HTTPCookieStorage = cookies
Static.instance = Alamofire.Manager(configuration: config)
}

return Static.instance
}()

manager.request(.GET, "https://stackoverflow.com")
.validate(statusCode: 200..<300)
.validate(contentType: ["text/html"])
.responseString { (response) in
guard response.result.isSuccess else {
print("Error: \(response.result.error)")
return
}
print("Result: \(response.result.value)")
}

P.S. You can also look into:

NSURLSessionConfiguration.ephemeralSessionConfiguration() - Returns a
session configuration that uses no persistent storage for caches,
cookies, or credentials.

how to ignore cached response using Alamofire?

Not sure why you are getting this error, but there are a number of ways to solve this error.

1.You can add timestamp to your API url so so that you would never get a cached response.

extension Date {
func toMillis() -> Int64! {
return Int64(self.timeIntervalSince1970 * 1000)
}
}

let currentTimeStamp = Date().toMillis()!
let url = "https://example.com?timestamp=\(currentTimeStamp)"

  1. You can do something like:

    var req = URLRequest(url: URL(string: "<URL>")!)
    req.httpMethod = "GET"
    req.setValue("application/json", forHTTPHeaderField: "Content-Type")
    req.setValue("<Auth KEY>", forHTTPHeaderField:"Authorization" )
    req.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData

    Alamofire.request(req).validate().responseJSON { response in ...

taken from

Alamofire loading from cache even when cache policy set to ReloadIgnoringLocalAndRemoteCacheData

I'm using this way in a project and it's working:

let mutableURLRequest = NSMutableURLRequest(URL: SERVICEURL)
mutableURLRequest.HTTPMethod = "POST"

mutableURLRequest.HTTPBody = self.createJson()
mutableURLRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
mutableURLRequest.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData

request(mutableURLRequest).validate().responseJSON{ response in...

Hope it helps.

Alamofire use configurable Caching

To elaborate on Jon's answer, the easiest way to achieve what you want is to just let the backend declare the cache semantics of this endpoint, then ensure that on the client side, URLSession uses a URLCache (which is probably the default anyway) and let URLSession and the backend do the rest. This requires, that you have control over the backend, though!

The more elaborate answer:

Here is just an example, how a server may return a response with declared cache semantics:

URL: https://www.example.com/ Status Code: 200
Age: 238645
Cache-Control: max-age=604800
Date: Tue, 12 Jan 2021 18:43:58 GMT
Etag: "3147526947"
Expires: Tue, 19 Jan 2021 18:43:58 GMT
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Vary: Accept-Encoding
x-cache: HIT

Accept-Ranges: bytes
Content-Encoding: gzip
Content-Length: 648
Content-Type: text/html; charset=UTF-8
Server: ECS (dcb/7EC7)

This server literally outputs the full range of what a server can declare regarding caching. The first eight headers (from Age to x-cache) declare the caching.

Cache-Control: max-age=604800 for example declares, that the data's freshness equals 604800 seconds. Having the date when the server created the data, the client can now check if the data is still "fresh".

Expires: Tue, 19 Jan 2021 18:43:58 GMT means the exact same thing, it declares when the data is outdated specifying the wall clock. This is redundant with the above declaration, but it is very clearly defined in the HTTP how clients should treat this.

Having an Age header is a hint, that the response has been actually delivered from a cache that exists between the client and the origin server. The age is the estimation of this data's age - the duration from when it has been created on the origin and when it has been delivered.

I don't wont to go into detail what every header means exactly and how a client and server should behave according HTTP since this is a very intense topic, but what you have to do is basically when you define an endpoint, is just to define the duration of the "freshness" of the returned data.

The whole details: Hypertext Transfer Protocol (HTTP/1.1): Caching

Once you came up with a good duration, Web-application frameworks (like Rails, SpringBoot, etc.) give great help with declaring cache semantics out of the box. Then Web-application frameworks will output the corresponding headers in the response - more or less "automagically".

The URLSession will automatically do the right thing according the HTTP protocol (well, almost). That is, it will store the response in the cache and when you perform a subsequent request it first looks for a suitable response in the cache and return that response if the "freshness" of the data is still given.

If that cached data is too old (according the given response headers and the current data and time), it will try to get a fresh data by sending the request to the origin server. Any upstream cache or eventually the origin server may then return fresh data. Your URLSession data task does all this transparently without giving you a clue whether the data comes from the cache or the origin server. And honestly, in most cases you don't need to know it.

Declaring the cache semantics according HTTP is very powerful and it usually should suit your needs. Also, the client may tailor its needs with specifying certain request headers, for example allowing to return even outdated data or ignoring any cached values, and much more.

Every detail may deserve a dedicated question and answer on SO.



Related Topics



Leave a reply



Submit