Skip to content

Instantly share code, notes, and snippets.

@donnywals
Created November 24, 2020 09:18
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save donnywals/f62759cf0085639b1fe388613da8fe90 to your computer and use it in GitHub Desktop.
Save donnywals/f62759cf0085639b1fe388613da8fe90 to your computer and use it in GitHub Desktop.
/*
Here's our goal:
let localDataStore = UserDataStore()
let remoteDataStore = UserApi()
let dataStore = CacheBackedDataStore(localDataStore, remoteDataStore)
dataStore.fetch(userID) { result in
// handle result
}
*/
protocol LocalStore {
associatedtype StoredType
func fetch(_ identifier: String) -> StoredType?
func persist(_ item: StoredType)
}
protocol RemoteStore {
associatedtype StoredType
func fetch(_ identifier: String, _ completion: (StoredType?) -> Void)
}
struct CacheBackedDataStore<Local: LocalStore, Remote: RemoteStore> where Local.StoredType == Remote.StoredType {
let localStore: Local
let remoteStore: Remote
func fetch(_ identifier: String, completion: @escaping (Remote.StoredType?) -> Void) {
if let object = localStore.fetch(identifier) {
completion(object)
} else {
remoteStore.fetch(identifier, { object in
if let unwrappedObject = object {
localStore.persist(unwrappedObject)
}
completion(object)
})
}
}
}
struct User {}
struct Video {}
class UserDataStore: LocalStore {
var user: User?
func fetch(_ identifier: String) -> User? {
print("FETCH")
return nil
}
func persist(_ item: User) {
print("PERSIST")
user = item
}
}
class RemoteUsers: RemoteStore {
func fetch(_ identifier: String, _ completion: (User?) -> Void) {
print("REMOTE FETCH")
completion(User())
}
}
let local = UserDataStore()
let remote = RemoteUsers()
class VideosDataStore: LocalStore {
func fetch(_ identifier: String) -> Video? {
return nil
}
func persist(_ item: Video) {
//
}
}
class RemoteVideos: RemoteStore {
func fetch(_ identifier: String, _ completion: (Video?) -> Void) {
completion(nil)
}
}
let local2 = VideosDataStore()
let remote2 = RemoteVideos()
let cacheBacked = CacheBackedDataStore(localStore: local, remoteStore: remote)
let cacheBacked2 = CacheBackedDataStore(localStore: local2, remoteStore: remote2)
cacheBacked.fetch("1") { user in
print("user fetched: \(user)")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment