This project is currently in beta and APIs are subject to change.
A Swift extension to use string-based API in a type-safe way.
All these fantastic API are compatible with traditional string-based API.
- Swift 5.2 (Xcode 11.4)
You can use
NSUbiquitousKeyValueStorewith almost the same API.
extension UserDefaults.DefaultKeys { static let intKey = Key<Int>("intKey") static let colorKey = Key<Color>("colorKey", transformer: .keyedArchive) static let pointKey = Key<CGPoint>("pointKey", transformer: .json) }let ud = UserDefaults.standard // Get & Set let value = ud[.intKey] ud[.stringKey] = "foo" // Modify ud[.intKey] += 1 ud[.stringKey] += "bar" // Typed array ud[.stringArrayKey].contains("foo") ud[.intArrayKey][0] += 1 // Work with NSKeyedArchiver ud[.colorKey] = UIColor.orange ud[.colorKey]?.redComponent // Work with JSONEncoder ud[.pointKey] = CGPoint(x: 1, y: 1) ud[.pointKey]?.x += 1 // Modern Key-Value Observing let observation = defaults.observe(.someKey, options: [.old, .new]) { (defaults, change) in print(change.newValue) } // KVO with deserializer let observation = defaults.observe(.rectKey, options: [.old, .new]) { (defaults, change) in // deserialized automatically if let rect = change.newValue { someView.frame = rect } } // Register with serializer ud.register(defaults: [ .intKey: 42, .stringKey: "foo", .colorKey: UIColor.blue, // serialized automatically .pointKey: CGPoint(x: 1, y: 1), ])If associated type of a key conforms DefaultConstructible, a default value will be constructed for nil result.
public protocol DefaultConstructible { init() }Here's types that conforms DefaultConstructible and its default value:
| Type | Default value |
|---|---|
| Bool | false |
| Int | 0 |
| Float/Double | 0.0 |
| String | "" |
| Data | [empty data] |
| Array | [] |
| Dictionary | [:] |
| Optional | nil |
Note: Optional also conforms DefaultConstructible, therefore a key typed as DefaultKey<Any?> aka DefaultKey<Optional<Any>> will still returns nil, which is the result of default construction of Optional.
You can always associate an optional type if you want an optional value.
extension UITableView.CellReuseIdentifiers { static let customCell : ID<MyCustomCell> = "CustomCellReuseIdentifier" }tableView.register(id: .customCell)let cell = tableView.dequeueReusableCell(withIdentifier: .customCell, for: indexPath) // Typed as MyCustomCell// That's it! extension MyCustomCell: UINibFromTypeGettable // Or, incase your nib name is not the same as class name extension MyCustomCell: UINibGettable { static var nibName = "MyNibName" } // Then register tableView.registerNib(id: .customCell)extension UIStoryboard.Identifiers { static let customVC: ID<MyCustomViewController> = "CustomVCStoryboardIdentifier" }// Also extend to get main storyboard let sb = UIStoryboard.main() let vc = sb.instantiateViewController(withIdentifier: .customVC) // Typed as MyCustomViewController// Define your associate keys extension YourClass.AssociateKeys { static let someKey: Key<Int> = "someKey" } // Use it! yourObject[.someKey] = 42GenericID is available under the MIT license. See the LICENSE file.