https://github.com/ddddxxx/genericid
A Swift extension to use string-based API in a type-safe way.
https://github.com/ddddxxx/genericid
userdefaults
Last synced: 9 months ago
JSON representation
A Swift extension to use string-based API in a type-safe way.
- Host: GitHub
- URL: https://github.com/ddddxxx/genericid
- Owner: ddddxxx
- License: mit
- Created: 2017-04-27T03:22:38.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2021-07-08T12:29:23.000Z (almost 5 years ago)
- Last Synced: 2025-09-10T19:52:16.697Z (10 months ago)
- Topics: userdefaults
- Language: Swift
- Homepage:
- Size: 164 KB
- Stars: 13
- Watchers: 4
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
> This project is currently in beta and APIs are subject to change.
# GenericID



[](https://codebeat.co/projects/github-com-ddddxxx-genericid-master)
A Swift extension to use string-based API in a **type-safe** way.
All these fantastic API are compatible with traditional string-based API.
## Requirements
- Swift 5.2 (Xcode 11.4)
## Type-safe `UserDefaults`
> You can use `NSUbiquitousKeyValueStore` with almost the same API.
### 1. Define your keys
```swift
extension UserDefaults.DefaultKeys {
static let intKey = Key("intKey")
static let colorKey = Key("colorKey", transformer: .keyedArchive)
static let pointKey = Key("pointKey", transformer: .json)
}
```
### 2. Have fun!
```swift
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),
])
```
### Default value
If associated type of a key conforms `DefaultConstructible`, a default value will be constructed for `nil` result.
```swift
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` aka `DefaultKey>` 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.
## Type-safe `UITableViewCell` / `UICollectionViewCell`
### 1. Define your reuse identifiers
```swift
extension UITableView.CellReuseIdentifiers {
static let customCell : ID = "CustomCellReuseIdentifier"
}
```
### 2. Register your cells
```swift
tableView.register(id: .customCell)
```
### 3. Dequeue your cells
```swift
let cell = tableView.dequeueReusableCell(withIdentifier: .customCell, for: indexPath)
// Typed as MyCustomCell
```
### XIB-based cells
```swift
// 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)
```
## Type-safe Storyboard
### 1. Define your storyboards identifiers
```swift
extension UIStoryboard.Identifiers {
static let customVC: ID = "CustomVCStoryboardIdentifier"
}
```
### 2. Use It!
```swift
// Also extend to get main storyboard
let sb = UIStoryboard.main()
let vc = sb.instantiateViewController(withIdentifier: .customVC)
// Typed as MyCustomViewController
```
## Type-safe Associated Object
```swift
// Define your associate keys
extension YourClass.AssociateKeys {
static let someKey: Key = "someKey"
}
// Use it!
yourObject[.someKey] = 42
```
## License
GenericID is available under the MIT license. See the [LICENSE file](LICENSE).