I'm having a weird bug that pop up out of no where. I'm almost done with my app and I'm testing it, and then I noticed the data isn't being updated. The database gets updated, and I can hit the url directly and see the data is being returned from the server correctly, but when I print the data in Swift, it doesn't change.
Once I rerun the app it will change (most of the time)
I'm using Alamofire, but I've also tried two other methods:
let url = NSURL(string: "http://www.stackoverflow.com")
let request = NSURLRequest(URL: url!)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in
println(NSString(data: data, encoding: NSUTF8StringEncoding))
}
and
let url = NSURL(string: "http://www.stackoverflow.com")
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
println(NSString(data: data, encoding: NSUTF8StringEncoding))
}
task.resume()
All 3 print out the same data.
I'm guessing it's a caching problem in Swift, but I haven't set anything to tell Swift to cache the data, and it's been working fine for the last few weeks.
The only thing I've done today was make a Git repo for my project.
Does anyone have any idea what could be causing this?
*edit:
Using Abhi Beckert's answer I tried this:
Conforming to the delegate NSURLConnectionDelegate
Adding:
func connection(connection: NSURLConnection, willCacheResponse cachedResponse: NSCachedURLResponse) -> NSCachedURLResponse?
{
return nil // never cache anything. ever.
}
and then to make the call:
let url:NSURL! = NSURL(string: "http://coffee.datausadev.com/api/getCoffeeBrands")
let request = NSURLRequest(URL: url, cachePolicy: .ReloadIgnoringLocalCacheData, timeoutInterval: 60)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {(response, data, error) in
println(NSString(data: data, encoding: NSUTF8StringEncoding))
}
This method still didn't work.
Here's how... When you're in Google Chrome, click on View, then select Developer, then Developer Tools. Alternatively, you can right click on a page in Chrome, then click Inspect. Click on the Network tab, then check the box to Disable cache.
By enabling the caching of GET requests, you can improve the response times of requests for resource data that were previously submitted by the same user. When caching is enabled, the data is retrieved from the browser cache instead of from the business object on the server.
The Cache-Control HTTP header field holds directives (instructions) — in both requests and responses — that control caching in browsers and shared caches (e.g. Proxies, CDNs).
Cache-control is an HTTP header used to specify browser caching policies in both client requests and server responses. Policies include how a resource is cached, where it's cached and its maximum age before expiring (i.e., time to live).
You need to set your controller object as the delegate for the NSURLConnection
:
let request = NSURLRequest(URL: requestURL, cachePolicy: .ReloadIgnoringLocalCacheData, timeoutInterval: 60)
self.currentConnection = NSURLConnection(request: request, delegate: self)
This also requires making self conform to the data source:
class MyController: NSURLConnectionDataDelegate {
And disable caching with the relevant delegate method:
func connection(connection: NSURLConnection, willCacheResponse cachedResponse: NSCachedURLResponse) -> NSCachedURLResponse?
{
return nil // never cache anything. ever.
}
The .ReloadIgnoringLocalCacheData
option on the URL request will disable reading the cache, and the willCacheResponse
delegate method disables writing to the cache. You need to use both of them.
Unfortunately this means you cannot use the sendAsynchronousRequest
convenience method and block callback - instead you'll have to use the delegate methods in NSURLConnectionDataDelegate
to process the response. Basically you've got to create an NSMutableData
object, and append to it as data comes in from the connection, until the connection tells you the request is finished or failed — then you can do something with the data.
As far as I know, it is impossible to fully disable caching while using sendAsynchronousRequest
. You might want to create a wrapper class around NSURLConnection
to make your code neater.
I tired everything, was not helpfull . This solution Worked For me in (Swift 3)
I called destroyCache() function after every HttpResponse.
public static func destroyCache() {
let fileManager = FileManager.default
let documentsUrl = fileManager.urls(for: FileManager.SearchPathDirectory.cachesDirectory, in: FileManager.SearchPathDomainMask.userDomainMask).first! as NSURL
let documentsPath = documentsUrl.path
let bundleIdentifier = Bundle.main.bundleIdentifier! as String
do {
if let documentPath = documentsPath
{
let fileNames = try fileManager.contentsOfDirectory(atPath: "\(documentPath)/\(bundleIdentifier)")
for fileName in fileNames {
let filePathName = "\(documentPath)/\(bundleIdentifier)/\(fileName)"
try fileManager.removeItem(atPath: filePathName)
}
}
} catch {
print("Could not clear: \(error)")
}
}
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