Last active
October 4, 2017 15:22
-
-
Save mikeash/12a13c9ae8cd3e35aa31a84523dee483 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SCROLL DOWN // | |
import Foundation | |
protocol TSUD { | |
associatedtype Value: Codable | |
init() | |
static var defaultValue: Value { get } | |
var stringKey: String { get } | |
} | |
extension TSUD { | |
var stringKey: String { | |
return String(describing: Self.self) | |
} | |
} | |
private protocol OptionalP { | |
var isNil: Bool { get } | |
} | |
extension Optional: OptionalP { | |
var isNil: Bool { return self == nil } | |
} | |
extension TSUD { | |
static var value: Value { | |
get { | |
return get() | |
} | |
set { | |
set(newValue) | |
} | |
} | |
static func get(_ nsud: UserDefaults = .standard) -> Value { | |
return self.init()[.standard] | |
} | |
static func set(_ value: Value, _ nsud: UserDefaults = .standard) { | |
self.init()[.standard] = value | |
} | |
subscript(nsud: UserDefaults) -> Value { | |
get { | |
return decode(nsud.object(forKey: stringKey)) ?? Self.defaultValue | |
} | |
nonmutating set { | |
nsud.set(encode(newValue), forKey: stringKey) | |
} | |
} | |
private func decode(_ plist: Any?) -> Value? { | |
guard let plist = plist else { return nil } | |
guard let data = try? PropertyListSerialization.data(fromPropertyList: plist, format: .binary, options: 0) else { return nil } | |
return try? PropertyListDecoder().decode(Value.self, from: data) | |
} | |
private func encode(_ value: Value?) -> Any? { | |
guard let value = value else { return nil } | |
if let opt = value as? OptionalP, opt.isNil { return nil } | |
do { | |
let data = try PropertyListEncoder().encode([value]) | |
let wrappedPlist = try PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [Any] | |
return wrappedPlist?[0] | |
} catch { | |
return nil | |
} | |
} | |
} | |
// START HERE // | |
//struct opt: TSUD { | |
// static let defaultValue: Int? = nil | |
//} | |
// | |
//opt.value = nil | |
// | |
//struct nonopt: TSUD { | |
// static let defaultValue = 0 | |
//} | |
// | |
//nonopt.value = 1 | |
struct enableThingy: TSUD { | |
static let defaultValue = false | |
} | |
struct numberOfThingies: TSUD { | |
static let defaultValue = 0 | |
} | |
struct optionalNumber: TSUD { | |
static let defaultValue: Int? = nil | |
} | |
enableThingy.value = false | |
enableThingy.value | |
UserDefaults.standard.object(forKey: "enableThingy") | |
enableThingy.value = true | |
enableThingy.value | |
UserDefaults.standard.object(forKey: "enableThingy") | |
numberOfThingies.value += 1 | |
numberOfThingies.value | |
UserDefaults.standard.object(forKey: "numberOfThingies") | |
optionalNumber.value | |
UserDefaults.standard.object(forKey: "optionalNumber") | |
optionalNumber.value = 3 | |
optionalNumber.value | |
UserDefaults.standard.object(forKey: "optionalNumber") | |
optionalNumber.value = nil | |
optionalNumber.value | |
UserDefaults.standard.object(forKey: "optionalNumber") | |
struct Widget: Codable { | |
var name: String | |
var purpose: String | |
var count: Int | |
} | |
struct lastWidget: TSUD { | |
static let defaultValue: Widget? = nil | |
} | |
lastWidget.value | |
lastWidget.value = Widget(name: "Plunger", purpose: "Plunging", count: 42) | |
UserDefaults.standard.object(forKey: "lastWidget") | |
lastWidget.value | |
lastWidget.value = nil | |
dump(UserDefaults.standard.object(forKey: "lastWidget")) | |
struct allWidgets: TSUD { | |
static let defaultValue: [Widget] = [] | |
} | |
allWidgets.value | |
allWidgets.value.append(Widget(name: "Whatever", purpose: "\(UUID())", count: Int(Date.timeIntervalSinceReferenceDate))) | |
allWidgets.value | |
UserDefaults.standard.object(forKey: "allWidgets") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment