Last active
December 11, 2015 18:28
-
-
Save dmrev/cd95b921c6c0c4cae54c to your computer and use it in GitHub Desktop.
Another statically-typed NSUserDefaults inspired by https://github.com/radex/SwiftyUserDefaults
This file contains 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
class SmartKeyBase: Equatable, Hashable { | |
private let defaults = NSUserDefaults.standardUserDefaults() | |
private(set) static var allKeys = Set<SmartKeyBase>() | |
let name: String | |
static func removeAllValues() { | |
allKeys.forEach { $0.removeValue() } | |
} | |
init(_ name: String) { | |
self.name = name | |
assert(!SmartKeyBase.allKeys.contains(self), "Duplicate SmartKey key found: \(name).") | |
SmartKeyBase.allKeys.insert(self) | |
} | |
func hasValue() -> Bool { | |
return defaults.objectForKey(name) != nil | |
} | |
func removeValue() { | |
defaults.removeObjectForKey(name) | |
} | |
var hashValue: Int { | |
return name.hashValue | |
} | |
} | |
func ==(left: SmartKeyBase, right: SmartKeyBase) -> Bool { | |
return left.name == right.name | |
} | |
class SmartKey<T>: SmartKeyBase { | |
let defaultValue: T | |
// `value` - default value for this key | |
init(_ name: String, _ value: T) { | |
self.defaultValue = value | |
super.init(name) | |
} | |
var value: T { | |
get { | |
if let value = defaults.objectForKey(name) { | |
switch value { | |
case let data as NSData: return NSKeyedUnarchiver.unarchiveObjectWithData(data) as! T | |
default: | |
if let value = value as? T { | |
return value | |
} | |
else { | |
removeValue() | |
// warning user? | |
return defaultValue | |
} | |
} | |
} | |
else { | |
return defaultValue | |
} | |
} | |
set { | |
switch newValue { | |
case let value as Int: defaults.setInteger(value, forKey: name) | |
case let value as Double: defaults.setDouble(value, forKey: name) | |
case let value as Bool: defaults.setBool(value, forKey: name) | |
case let value as String: defaults.setObject(value, forKey: name) | |
case let value as NSDate: defaults.setObject(value, forKey: name) | |
//case let value as NSData: defaults.setObject(value, forKey: name) | |
case let value as NSObject where value is NSCoding: defaults.setObject(NSKeyedArchiver.archivedDataWithRootObject(value), forKey: name) | |
default: assertionFailure("Unsupported `value` type: \(newValue.dynamicType).") | |
} | |
} | |
} | |
var optionalValue: T? { | |
return hasValue() ? value : nil | |
} | |
} | |
extension SmartKey: CustomStringConvertible { | |
var description: String { | |
return "\(name): \(optionalValue), \(defaultValue)" | |
} | |
} |
This file contains 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
struct UserDefaults { | |
static let currentMap = SmartKey<String>("currentMap", "moscow") | |
static let count = SmartKey<Int>("count", 0) | |
static let color = SmartKey<UIColor>("color", .whiteColor()) | |
static let ints = SmartKey<[Int]>("ints", [1, 2]) | |
static let recentRoutes = SmartKey<[SavedRoute]>("recentRoutes", []) // @objc(SavedRoute) | |
// class SavedRoute: NSObject, NSCoding { ... } | |
static let date = SmartKey<NSDate>("date", NSDate.distantPast()) | |
static let dict = SmartKey<[String: SavedRoute]>("dict", ["first": SavedRoute()]) | |
static let url = SmartKey<NSURL>("url", NSURL(string: "http://localhost")!) | |
} | |
UserDefaults.count.value++ | |
UserDefaults.ints.value += [3] | |
// ...etc. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment