Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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()
}
}
@steipete

This comment has been minimized.

@ArkadiGiniApps

This comment has been minimized.

Copy link

@ArkadiGiniApps ArkadiGiniApps commented Nov 15, 2020

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

@steipete

This comment has been minimized.

Copy link
Owner Author

@steipete steipete commented Nov 15, 2020

Indeed. I mentioned this in the blog post.

@steve-mnp

This comment has been minimized.

Copy link

@steve-mnp steve-mnp commented Mar 2, 2021

Thanks for this excellent article and accompanying gist!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment