Using URLCache with download tasks (NSURLCache & NSURLSessionDownloadTask)
import Foundation | |
import os.log | |
class URLCacheTest { | |
let logger = Logger(subsystem: "URLCacheTest", category: "main") | |
// HTTP HEADERS: | |
// Date: Wed, 04 Nov 2020 11:13:24 GMT | |
// Server: Apache | |
// Strict-Transport-Security: max-age=63072000; includeSubdomains; preload | |
// X-Content-Type-Options: nosniff | |
// X-Frame-Options: SAMEORIGIN | |
// Last-Modified: Sun, 19 May 2002 14:49:00 GMT | |
// Accept-Ranges: bytes | |
// Content-Length: 20702285 | |
// Content-Type: application/pdf | |
let flightPlanURL = URL(string: "https://www.hq.nasa.gov/alsj/a17/A17_FlightPlan.pdf")! | |
// Custom URL cache with 1 GB disk storage | |
lazy var cache: URLCache = { | |
let cachesURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0] | |
let diskCacheURL = cachesURL.appendingPathComponent("DownloadCache") | |
let cache = URLCache(memoryCapacity: 100_000_000, diskCapacity: 1_000_000_000, directory: diskCacheURL) | |
logger.info("Cache path: \(diskCacheURL.path)") | |
return cache | |
}() | |
// Custom URLSession that uses our cache | |
lazy var session: URLSession = { | |
let config = URLSessionConfiguration.default | |
config.urlCache = cache | |
return URLSession(configuration: config) | |
}() | |
init() { | |
let documentURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] | |
let targetURL = documentURL.appendingPathComponent(flightPlanURL.lastPathComponent) | |
downloadFile(remoteURL: flightPlanURL, targetURL: targetURL) | |
} | |
func downloadFile(remoteURL: URL, targetURL: URL) { | |
let request = URLRequest(url: remoteURL) | |
let downloadTask = session.downloadTask(with: request) { url, response, error in | |
self.logger.info("Download Task complete") | |
// Store data in cache | |
if let response = response, let url = url, | |
self.cache.cachedResponse(for: request) == nil, | |
let data = try? Data(contentsOf: url, options: [.mappedIfSafe]) { | |
self.cache.storeCachedResponse(CachedURLResponse(response: response, data: data), for: request) | |
} | |
// Move file to target location | |
guard let tempURL = url else { return } | |
_ = try? FileManager.default.replaceItemAt(targetURL, withItemAt: tempURL) | |
} | |
downloadTask.resume() | |
} | |
} |
This comment has been minimized.
This comment has been minimized.
A small side note, using URLSession with background configuration will ignore the URLCache object, its a "minor" not well documented fact. I had it confirmed with a ATS a few years back as far as i know its still there, and very poorly documented |
This comment has been minimized.
This comment has been minimized.
Indeed. I mentioned this in the blog post. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
https://pspdfkit.com/blog/2020/downloading-large-files-with-urlsession/