Skip to content

Instantly share code, notes, and snippets.

@ts95
Created May 27, 2020 11:39
Show Gist options
  • Save ts95/8a69e242d7aae7208c1554f4bafa935a to your computer and use it in GitHub Desktop.
Save ts95/8a69e242d7aae7208c1554f4bafa935a to your computer and use it in GitHub Desktop.
Swift PropertyStore class for protocols
class PropertyStore<Root> {
private var store = [AnyHashable : Any]()
/// Runs the computedValue closure once and stores its result in a cache for the duration
/// of the property store object's lifetime. Subsequent calls to this method will return the cached value.
func cached<T>(_ keyPath: KeyPath<Root, T>, _ computedValue: @escaping () -> T) -> T {
if let storedValue = store[keyPath] as? T {
return storedValue
}
let value = computedValue()
store[keyPath] = value
return value
}
func clear<T>(property keyPath: KeyPath<Root, T>) {
store[keyPath] = nil
}
func clearAll() {
store.removeAll()
}
}
// Example usage
protocol HasPropertyStore {
var ps: PropertyStore<Self> { get }
}
protocol HasLocationCoordinate: HasPropertyStore {
var latitude: Double { get }
var longitude: Double { get }
var locationCoordiante: CLLocationCoordinate2D { get }
}
extension HasLocationCoordinate {
var locationCoordiante: CLLocationCoordinate2D {
ps.cached(\.locationCoordiante) {
.init(latitude: self.latitude, longitude: self.longitude)
}
}
}
struct PointOfInterest: Codable, HasLocationCoordinate {
let name: String
let latitude: Double
let longitude: Double
let ps = PropertyStore<PointOfInterest>()
enum CodingKeys: String, CodingKey {
case name
case latitude
case longitude
}
}
let poi = PointOfInterest(name: "Nationaltheatret", latitude: 59.914472, longitude: 10.734372)
print(poi.locationCoordiante)
print(poi.locationCoordiante)
@ts95
Copy link
Author

ts95 commented Aug 10, 2020

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