Just discovered that the function storeCachedResponse(_ cachedResponse: CachedURLResponse, for request: URLRequest) works asynchronously. That is, the result is not returned immediately after execution. I did not find a description of this in the official documentation. See example:
cache = URLCache(memoryCapacity: 0, diskCapacity: 100 * 1024 * 1024, diskPath: "myCache")
let config = URLSessionConfiguration.default
config.requestCachePolicy = .returnCacheDataElseLoad
config.urlCache = cache
let session = URLSession(configuration: config)
session.dataTask(with: request, completionHandler: {[unowned self]
(data, response, error) in
if let data = data, let response = response, ((response as HTTPURLResponse)?.statusCode ?? 500) < 300 {
let cachedData = CachedURLResponse(response: response, data: data)
self.cache.storeCachedResponse(cachedData, for: request)
let testCachedData = self.cache.cachedResponse(for: request)
}
}
Theoretically testCachedData must contain cached response. But what it actually contains:
testCachedData?.response.url // Ok
testCachedData?.isEmpty // false
testCachedData?.data // 0 bytes!!!
Although testCachedData?.data says it contains 0 bytes, we can write this data to a file, and this file will contain real data, not 0. If we deep into local cache directory (~/Library/Caches/myApp/MyCache) when pausing at breakpoint right after cachedResponse call, we can see that folder with cached files (fsCachedData) doesn't exist yet. Now let's insert delay between storeCachedResponse and cachedResponse:
cache = URLCache(memoryCapacity: 0, diskCapacity: 100 * 1024 * 1024, diskPath: "myCache")
let config = URLSessionConfiguration.default
config.requestCachePolicy = .returnCacheDataElseLoad
config.urlCache = cache
let session = URLSession(configuration: config)
session.dataTask(with: request, completionHandler: {[unowned self]
(data, response, error) in
if let data = data, let response = response, ((response as HTTPURLResponse)?.statusCode ?? 500) < 300 {
let cachedData = CachedURLResponse(response: response, data: data)
self.cache.storeCachedResponse(cachedData, for: request)
delay(5) // JUST 5 SEC DELAY
let testCachedData = self.cache.cachedResponse(for: request)
}
}
Now:
testCachedData?.response.url // Ok
testCachedData?.isEmpty // false
testCachedData?.data // contains bytes
So, after 5 sec delay we see that cached files folder (fsCachedData) exists and contains cached file (e.g. D8A30D21-C8F1-4FCA-967E-F6B440998173).
The point is how to catch the completion of storeCachedResponse?
I'm going to use cached files right after they are created. Moreover, I'm going to handle cached files directly, and it's not the best solution to set delay.