Alamofire - NSURLCache is not working?
Asked Answered
C

6

9

I set my cache as below

var cacheSizeMemory = 20 * 1024 * 1024
var cacheSizeDisk = 100 * 1024 * 1024
var sharedCache = NSURLCache(memoryCapacity: cacheSizeMemory, diskCapacity: cacheSizeDisk, diskPath: "SOME_PATH")
NSURLCache.setSharedURLCache(sharedCache)

Create request with cache policy

var request = NSMutableURLRequest(URL: NSURL(string: "\(baseUrl!)\(path)")!, cachePolicy: .ReturnCacheDataElseLoad, timeoutInterval: timeout)

Make a request and get a response with following Cache-Control private, max-age=60

Then try to check the cache

var cachedResponse = NSURLCache.sharedURLCache().cachedResponseForRequest(urlRequest)

value is nil

Any thoughts?

Castigate answered 5/1, 2015 at 18:33 Comment(1)
I am having the exact same problem right now, no solution yet.Lilley
C
9

I ended up manually adding Cache-Control as private in the header of my request and it now works. Don't even need to manually check the cache, Alamofire does it for you

let cachePolicy: NSURLRequestCachePolicy = isReachable() ? .ReloadIgnoringLocalCacheData : .ReturnCacheDataElseLoad

var request = NSMutableURLRequest(URL: NSURL(string: "\(baseUrl!)\(path)")!, cachePolicy: cachePolicy, timeoutInterval: timeout)

request.addValue("private", forHTTPHeaderField: "Cache-Control")

var alamoRequest = Manager.sharedInstance.request(urlRequest)
Castigate answered 6/1, 2015 at 0:5 Comment(4)
Would you mind providing us with a code snippet of this?Lilley
it does not work on iOS 8.x however it works fine on iOS 7.1 Is there any way to make it work on iOS 8.x?Bradleybradly
Any clue how does this work with iOS 9? I have tried this out but no help!Thriller
does not work for me either. Server set its cache headers for 10 mins but even I use ReturnCacheDataElseLoad policy, after 10 mins cannot call images from cacheUwton
T
19

I was able to manually cache pages by writing them to the sharedURLCache like this:

    Alamofire.request(req)
        .response {(request, res, data, error) in
            let cachedURLResponse = NSCachedURLResponse(response: res!, data: (data as NSData), userInfo: nil, storagePolicy: .Allowed)
            NSURLCache.sharedURLCache().storeCachedResponse(cachedURLResponse, forRequest: request)
        }

NSURLCache seems to respect the headers sent by the server, even if you configure the opposite everywhere else in your code.

The Wikipedia API, for example, sends

Cache-control: private, must-revalidate, max-age=0

Which translates to: Must revalidate after 0 seconds.
So NSURLCache says: “OK, I won’t cache anything.”

But by manually saving the response to the cache, it works. At least on iOS 8.2.

Almost lost my mind on this one. :)

Triglyceride answered 1/4, 2015 at 16:54 Comment(1)
Nice solution. With this one, are we sure that the NSURLCache always returns the cached response, unregarded the headers?Pioneer
C
9

I ended up manually adding Cache-Control as private in the header of my request and it now works. Don't even need to manually check the cache, Alamofire does it for you

let cachePolicy: NSURLRequestCachePolicy = isReachable() ? .ReloadIgnoringLocalCacheData : .ReturnCacheDataElseLoad

var request = NSMutableURLRequest(URL: NSURL(string: "\(baseUrl!)\(path)")!, cachePolicy: cachePolicy, timeoutInterval: timeout)

request.addValue("private", forHTTPHeaderField: "Cache-Control")

var alamoRequest = Manager.sharedInstance.request(urlRequest)
Castigate answered 6/1, 2015 at 0:5 Comment(4)
Would you mind providing us with a code snippet of this?Lilley
it does not work on iOS 8.x however it works fine on iOS 7.1 Is there any way to make it work on iOS 8.x?Bradleybradly
Any clue how does this work with iOS 9? I have tried this out but no help!Thriller
does not work for me either. Server set its cache headers for 10 mins but even I use ReturnCacheDataElseLoad policy, after 10 mins cannot call images from cacheUwton
U
4

I found that URLCache does not save responses bigger than 5% (1/20) of capacity.

Default cache has memoryCapacity = 512000, it does not save to memory responses greater than 25600.

As a solution extend capacity

Unyielding answered 27/3, 2018 at 11:16 Comment(1)
Thanks this led to finding the following: developer.apple.com/documentation/foundation/… The response size is small enough to reasonably fit within the cache. (For example, if you provide a disk cache, the response must be no larger than about 5% of the disk cache size.)Aalesund
G
2

[Swift solution for resolving expiration of NSURLcache]

I think that main problem here is this: ReturnCacheDataElseLoad.

@arayax gave you the answer that will fix that probably, but my solution would be something like this:

Since I'm using Alamofire for Network requests I've set my configuration:

  configuration.requestCachePolicy = .ReturnCacheDataElseLoad

And when I make request I do check internet connectivity, if it is true, then clear NSURLCache, so it will force Alamofire to make request on server and not from cache:

    if Reachability.isConnectedToNetwork() == true {
        ConfigService.cache.removeAllCachedResponses()
    }

    ConfigService.manager?.request(.GET, ...

I hope this will help, maybe for other type of problems with NSURLCache :)

Gere answered 28/3, 2016 at 5:43 Comment(0)
S
1

For me it was Pragma →no-cache after removing this everything worked.

Shutdown answered 17/1, 2017 at 4:20 Comment(0)
C
0

This is how I got the cache to work with Alamofire 4 and swift 3 (Semi full function for reference):

 func getTheList(courseId : String )->  Void{
        appConstants.sharedInstance.startLoading()
        let TheURL = DEFAULT_APP_URL + "api/getMyList?Id="+ID
        let urlString = NSURL(string: TheURL)
        var mutableURLRequest = URLRequest(url: urlString! as URL)
        mutableURLRequest.httpMethod = "GET"
        mutableURLRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
        mutableURLRequest.cachePolicy = NSURLRequest.CachePolicy.returnCacheDataElseLoad


        Alamofire.request(mutableURLRequest)
            .responseJSON
           {.......
Cowry answered 8/5, 2017 at 14:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.