Hi !
Usually you want to make your app behave better under poor network conditions but you also want it to fetch the latest data when available. In terms of caching policy it would mean : “loadFromWebElseUseCache”
Unfortunately it does not exists. What’s available is :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public enum CachePolicy : UInt { case useProtocolCachePolicy case reloadIgnoringLocalCacheData case reloadIgnoringLocalAndRemoteCacheData // Unimplemented public static var reloadIgnoringCacheData: NSURLRequest.CachePolicy { get } case returnCacheDataElseLoad case returnCacheDataDontLoad case reloadRevalidatingCacheData // Unimplemented } |
Some of them aren’t even implemented ! I solved the problem by using two different URLSession :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
func load(url: URL, completion: @escaping (Data?, Error?, Error?) -> ()) { let networkSession = session(withPolicy: .reloadIgnoringLocalCacheData) let localSession = session(withPolicy: .returnCacheDataDontLoad) networkSession.dataTask(with: url) { (networkData, networkResponse, networkError) in guard networkError == nil else { localSession.dataTask(with: url) { (cacheData, cacheResponse, cacheError) in completion(cacheData, networkError, cacheError) }.resume() } completion(networkData,nil,nil) }.resume() } func session(withPolicy policy:NSURLRequest.CachePolicy, timeout: TimeInterval = 5)-> URLSession { let config = URLSessionConfiguration.default config.requestCachePolicy = policy let cache = URLCache(memoryCapacity: 4 * 1024 * 1024, diskCapacity: 40 * 1024 * 1024, diskPath: "offline-cache") URLCache.shared = cache config.timeoutIntervalForRequest = 5 config.urlCache = cache return URLSession(configuration: config) } |
Hope you like it !
Cheers,
MAB