Skip to content

Instantly share code, notes, and snippets.

@jarosan
Created January 2, 2019 14:32
Show Gist options
  • Save jarosan/955826fae837539c9c49d404a9a34df8 to your computer and use it in GitHub Desktop.
Save jarosan/955826fae837539c9c49d404a9a34df8 to your computer and use it in GitHub Desktop.
class FlioDefaults {
enum Key: String {
case unloggedUserVouchers = "FLIOUnloggedUserVouchers"
case sentCalendarEvents = "FLIOSentCalendarEventsKey"
case recentSearchAirportIds = "recentAirportSearchUIDs"
case calendarPermissionsGranted = "FLIOcalendarPermissionsGranted"
case calendarPermissionsRequested = "FLIOcalendarPermissionsRequested"
}
// static let foo = NativeProperty<String>(.testKey, default: "foo")
// static let foo2 = NativeProperty<String?>(.testKey2, default: nil)
static let sentCalendarEvents = NativeProperty<[String: Date]>(.sentCalendarEvents, default: [:])
static let recentSearchAirportIds = NativeProperty<[Int]>(.recentSearchAirportIds, default: [])
static let calendarPermissionsGranted = NativeProperty<Bool>(.calendarPermissionsGranted, default: false)
static let calendarPermissionsRequested = NativeProperty<Bool>(.calendarPermissionsRequested, default: false)
static let unloggedUserVouchers = FlioProperty<[Voucher]>(.unloggedUserVouchers, default: [])
}
class FlioProperty<Value: Codable>: NativeProperty<Value> {
override func readValue() -> Value? {
guard let rawData = UserDefaults.standard.data(forKey: key.rawValue) else { return nil }
return try? JSONDecoder().decode(Value.self, from: rawData)
}
override func prepareDataForWrite(_ newValue: Value) -> Any? {
let encoder = JSONEncoder()
return try? encoder.encode(newValue)
}
}
class NativeProperty<Value> {
let key: FlioDefaults.Key
private let defaultValue: Value
private var cachedValue: Value?
init(_ key: FlioDefaults.Key, default defaultValue: Value) {
self.key = key
self.defaultValue = defaultValue
}
public var value: Value {
get { return fetchValue() }
set { modify(newValue) }
}
func clear() {
UserDefaults.standard.removeObject(forKey: key.rawValue)
}
func readValue() -> Value? {
return UserDefaults.standard.object(forKey: key.rawValue) as? Value
}
func prepareDataForWrite(_ newValue: Value) -> Any? {
return newValue
}
private func fetchValue() -> Value {
if let cachedValue = cachedValue {
return cachedValue
}
let currentValue = readValue() ?? defaultValue
cachedValue = currentValue
return currentValue
}
private func modify(_ newValue: Value) {
if let data = prepareDataForWrite(newValue) {
UserDefaults.standard.set(data, forKey: key.rawValue)
UserDefaults.standard.synchronize()
}
cachedValue = nil
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment