Skip to content

Instantly share code, notes, and snippets.

@RomanVolkov
Created January 9, 2017 13:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RomanVolkov/9301e7879d7fb47208207e4d1f197f2c to your computer and use it in GitHub Desktop.
Save RomanVolkov/9301e7879d7fb47208207e4d1f197f2c to your computer and use it in GitHub Desktop.
Cacher for iOS
import Foundation
public protocol Cachable {
var fileName: String { get }
func transform() -> Data
}
final class Cacher {
let destination: URL
private let queue = OperationQueue()
enum CacheDestination {
case temporary
case atFolder(String)
}
init(destination: CacheDestination) {
switch destination {
case .temporary:
self.destination = URL(fileURLWithPath: NSTemporaryDirectory())
case .atFolder(let folder):
let documentFolder = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
self.destination = URL(fileURLWithPath: documentFolder).appendingPathComponent(folder, isDirectory: true)
}
let fileManager = FileManager.default
do {
try fileManager.createDirectory(at: self.destination, withIntermediateDirectories: true, attributes: nil)
}
catch {
fatalError("Unable to create cache URL: \(error)")
}
}
func persist(item: Cachable, completion: @escaping (_ url: URL) -> Void) {
let url = destination.appendingPathComponent(item.fileName, isDirectory: false)
let operation = BlockOperation {
do {
try item.transform().write(to: url, options: [.atomicWrite])
} catch {
fatalError("Failed to write item to cache: \(error)")
}
}
operation.completionBlock = {
completion(url)
}
queue.addOperation(operation)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment