Только что обнаружил, что функция storeCachedResponse (_cachedResponse: CachedURLResponse, для request: URLRequest) работает асинхронно.То есть результат не возвращается сразу после выполнения.Я не нашел описания этого в официальной документации.Смотрите пример:
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)
}
}
Теоретически testCachedData должен содержать кэшированный ответ.Но что он на самом деле содержит:
testCachedData?.response.url // Ok
testCachedData?.isEmpty // false
testCachedData?.data // 0 bytes!!!
Хотя testCachedData? .Data говорит, что он содержит 0 байтов, мы можем записать эти данные в файл, и этот файл будет содержать реальные данные, а не 0. Если мы углубимся вкаталог локального кэша (~ / Library / Caches / myApp / MyCache) при остановке в точке останова сразу после вызова cachedResponse мы видим, что папка с кэшированными файлами (fsCachedData) еще не существует.Теперь давайте вставим задержку между storeCachedResponse и 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)
}
}
Сейчас:
testCachedData?.response.url // Ok
testCachedData?.isEmpty // false
testCachedData?.data // contains bytes
Итак, после 5-секундной задержки мы видим, что папка с кэшированными файлами (fsCachedData) существует и содержит кэшированный файл (например, D8A30D21-C8F1-4FCA-967E-F6B440998173).
Дело в том, как отследить завершение storeCachedResponse?
Я собираюсь использовать кэшированные файлы сразу после их создания.Более того, я собираюсь работать с кэшированными файлами напрямую, и это не лучшее решение для установки задержки.