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)"
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
Tutorial on How to Drag and Drop Item from Uitableview to Uitableview
Check If Optional Array Is Empty
How to Add Equal Spacing and Equal Width for Button in iOS Auto Layout
How to Add Animation to Launch Screen in iOS 9.3 Using Objective C
Code Sign Error:Bundle Format Unrecognized, Invalid, or Unsuitable
Install Simulator Sdk 4.3 to Xcode 4.4 on Mountain Lion
What's the Difference Between "Architectures" and "Valid Architectures" in Xcode Build Settings
How to Underline a Uilabel in Swift
Dealing with iPad Mini Screen Size
What Is the Life Cycle of an iPhone Application
Tweening/Interpolating Between Two Cgpaths/Uibeziers
Autoshrink on a Uilabel with Multiple Lines
Handling Private Frameworks in Xcode ≥ 7.3
Defaultcalendarfornewevents Failed
Failed to Emit Precompiled Header for Bridging Header