If I set the capacity of the disk cache to less than 5MB, It doesn't work.
Through the print statement, I checked that the value of the currentDiskUsage
did not rise at all, and I also checked that the image has been making network requests every time because there is no cached data even if I shut down and run the app again. I'm simply wondering why this is happening.
Also, I wonder what kind of eviction policy the disk cache follows. I was so curious that I tried to find out through the link [here], but there seems to be no implementation of disk cache at all.
Below is the code I used. I'm attaching it together just in case.
import UIKit
protocol Cacheable {
func getCachedResponse(
for path: String,
completion: @escaping (Result<Data, CacheError>) -> Void
)
func save(
for path: String,
data: Data
)
}
final class CacheManager {
static let shared = CacheManager()
private let imageCache: URLCache
init() {
imageCache = URLCache(
memoryCapacity: 4 * 1024 * 1024, // 4MB
diskCapacity: 4 * 1024 * 1024 // 4MB
)
}
}
extension CacheManager: Cacheable {
func getCachedResponse(
for path: String,
completion: @escaping (Result<Data, CacheError>) -> Void
) {
if let url = URL(string: path),
let cachedResponse = imageCache.cachedResponse(for: URLRequest(url: url)) {
completion(.success(cachedResponse.data))
return
}
completion(.failure(.noCachedResponse))
}
func save(
for path: String,
data: Data
) {
guard let url = URL(string: path) else { return }
let response = URLResponse(
url: url,
mimeType: nil,
expectedContentLength: 0,
textEncodingName: nil
)
if let uiImage = UIImage(data: data),
let compressedData = uiImage.jpegData(compressionQuality: 0.8) {
#if DEBUG
let formmatter = ByteCountFormatter()
formmatter.allowedUnits = [.useMB]
formmatter.countStyle = .file
print("""
=== Original size: \(formmatter.string(fromByteCount: Int64(data.count)))
=== Cached size: \(formmatter.string(fromByteCount: Int64(compressedData.count)))
""")
#endif
let cachedResponse = CachedURLResponse(
response: response,
data: compressedData
)
imageCache.storeCachedResponse(
cachedResponse,
for: URLRequest(url: url)
)
}
}
}
The policy used be URLCache
is an implementation detail. It has changed in the past and it’s very likely to change again in the future. The only real guarantee you have here is that, in general, the cache will work reasonably well for web-browser-y apps, which is its core ‘market’.
In terms of how things are currently implemented, yes, there’s currently a 5 MiB minimum size for the on-disk cache. But, to reiterate, that’s an implementation detail, not an API guarantee.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"