
This video is only available to subscribers. Start a subscription today to get access to this and 470 other videos.
Codable as a Caching Layer
Setting up storage options
We'll want to be able to easily switch the location of the stored files. We'll start by creating an enum
to describe the types
of data we will store:
enum StorageType {
case cache
case permanent
var searchPathDirectory: FileManager.SearchPathDirectory {
switch self {
case .cache: return .cachesDirectory
case .permanent: return .documentDirectory
}
}
var folder: URL {
let path = NSSearchPathForDirectoriesInDomains(searchPathDirectory, .userDomainMask, true).first!
let subfolder = "com.nsscreencast.TopRepos.json_storage"
return URL(fileURLWithPath: path).appendingPathComponent(subfolder)
}
func clearStorage() {
try? FileManager.default.removeItem(at: folder)
}
}
This will allow us to specify that we want data to be stored in the Caches folder, allowing the OS to clean it up as it sees fit. If you have data that needs to be durable (say, like profile information for the currently logged in user), then you can use the Documents folder.
Saving / Loading Data on Disk
Next we'll create our storage class. We'll call it LocalJSONStore
. It will be generic over the type of data we wish to save, so we will need to make sure that the generic type is Codable
:
class LocalJSONStore<T> where T : Codable {
let storageType: StorageType
let filename: String
init(storageType: StorageType, filename: String) {
self.storageType = storageType
self.filename = filename
ensureFolderExists()
}
// ... snip
}
Saving an object
func save(_ object: T) {
do {
let data = try JSONEncoder().encode(object)
try data.write(to: fileURL)
} catch let e {
print("ERROR: \(e)")
}
}
Retrieving a saved object
var storedValue: T? {
guard FileManager.default.fileExists(atPath: fileURL.path) else {
return nil
}
do {
let data = try Data(contentsOf: fileURL)
let jsonDecoder = JSONDecoder()
return try jsonDecoder.decode(T.self, from: data)
} catch let e {
print("ERROR: \(e)")
return nil
}
}
It is important to note that errors are to be expected here. The data may become outdated as the application is updated, and so it may fail to decode back into your object. If this happens it is okay because we just won't have cached data, and the application will have to fetch and save a new copy.