Skip to content

Instantly share code, notes, and snippets.

@jameszaghini
Last active February 13, 2020 04:49
Show Gist options
  • Select an option

  • Save jameszaghini/1b8066b92f6eb59c4dec656f13958f05 to your computer and use it in GitHub Desktop.

Select an option

Save jameszaghini/1b8066b92f6eb59c4dec656f13958f05 to your computer and use it in GitHub Desktop.
WIP Swift repository pattern
import Foundation
import Combine
struct Thing {}
protocol ThingRepository {
func getAll(completion: @escaping ([Thing]) -> ())
}
protocol ThingDataSource {
func getAll(completion: @escaping ([Thing]) -> ())
}
public class RemoteThingDataSource: ThingDataSource {
// Use distantPast so we done't need to unwrap lastFetch
private(set) var lastFetch = Date.distantPast
func getAll(completion: @escaping ([Thing]) -> ()) {
lastFetch = Date()
// TODO: fetch from API
let things = [Thing()]
completion(things)
}
}
public struct LocalThingDataSource: ThingDataSource {
func getAll(completion: @escaping ([Thing]) -> ()) {
// TODO: read from disk
let things = [Thing()]
completion(things)
}
}
class ThingDataRepository: ThingRepository {
private let remoteDataSource: RemoteThingDataSource
private let localDataSource: LocalThingDataSource
private let staleThreshold: TimeInterval = 5 * 60
@Published private(set) var things: [Thing] = []
init(remoteDataSource: RemoteThingDataSource, localDataSource: LocalThingDataSource) {
self.remoteDataSource = remoteDataSource
self.localDataSource = localDataSource
}
func getAll(completion: @escaping ([Thing]) -> ()) {
let isCachedDataStale = remoteDataSource.lastFetch > Date().addingTimeInterval(-staleThreshold)
if isCachedDataStale {
remoteDataSource.getAll { completion($0) }
} else {
localDataSource.getAll { completion($0) }
}
}
}
let localThingDataSource = LocalThingDataSource()
let remoteThingDataSource = RemoteThingDataSource()
let repository = ThingDataRepository(remoteDataSource: remoteThingDataSource, localDataSource: localThingDataSource)
repository.getAll { print($0) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment