Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tasanobu-zz/TypedDefaults
TypedDefaults is a utility library to type-safely use NSUserDefaults.
https://github.com/tasanobu-zz/TypedDefaults
Last synced: 17 days ago
JSON representation
TypedDefaults is a utility library to type-safely use NSUserDefaults.
- Host: GitHub
- URL: https://github.com/tasanobu-zz/TypedDefaults
- Owner: tasanobu-zz
- License: mit
- Created: 2016-03-15T00:26:38.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2017-10-30T09:44:02.000Z (about 7 years ago)
- Last Synced: 2024-10-29T19:52:51.348Z (about 2 months ago)
- Language: Swift
- Homepage:
- Size: 29.3 KB
- Stars: 110
- Watchers: 3
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-ios - TypedDefaults - TypedDefaults is a utility library to type-safely use NSUserDefaults. (Database / Getting Started)
README
TypedDefaults
===[![Language](http://img.shields.io/badge/language-swift-brightgreen.svg?style=flat
)](https://developer.apple.com/swift)
[![CocoaPods](https://img.shields.io/cocoapods/v/TypedDefaults.svg)]()
[![License](http://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat
)](http://mit-license.org)
[![Issues](https://img.shields.io/github/issues/tasanobu/TypedDefaults.svg?style=flat
)](https://github.com/tasanobu/TypedDefaults/issues?state=open)`TypedDefaults` is a utility library to type-safely use NSUserDefaults.
#### Motivation
The talk *[Keep Calm and Type Erase On](https://realm.io/news/tryswift-gwendolyn-weston-type-erasure/)* by [Gwendolyn Weston](https://github.com/gwengrid) at [try! Swift 2016](http://www.tryswiftconf.com) is great and it inspired me to apply the technique *Type Erasure* for actual cases in app development.#### Installation
- Install with CocoaPods```ruby
use_frameworks!platform :ios, '8.0'
pod 'TypedDefaults'
```#### Requirements
- iOS 8.0+
- Swift 4.0
- Xcode 9## Features
- Custom types can be type-safely stored in NSUserDefaults
- Dependency Injection support## Usage
### Custom types
Custom types can be type-safely stored in NSUserDefaults.
Custom types only need to adopt `DefaultsConvertible` protocol as described later. No need to inherit NSObject.
Therefore, `Swift native Class` `Struct` and `Enum` are available for custom types.(Of course, subclasses of NSObject are available.)#### `DefaultsConvertible` protocol
```swift
public protocol DefaultConvertible {static var key: String { get }
init?(_ object: Any)
func serialize() -> Any
}
```Custom types are stored in NSUserDefaults as AnyObject.
`serialize()` is called when saving and `init?(_ object:)` is called when getting from NSUserDefaults.
It's assuemd each custom type and one configuration used in app is one-to-one relation.
Therefore, `key` is prepared as type property in order to assign `key` to one `custom type`.##### Example of custom type
This is an example of the custom type with `flag for saving photo to CameraRoll` and `Photo Size` as camera configuration.```swift
struct CameraConfig: DefaultConvertible {
enum Size: Int {
case Large, Medium, Small
}var saveToCameraRoll: Bool
var size: Size// MARK: DefaultConvertible
static let key = "CameraConfig"
init?(_ object: Any) {
guard let dict = object as? [String: Any] else {
return nil
}self.saveToCameraRoll = dict["cameraRoll"] as? Bool ?? true
if let rawSize = dict["size"] as? Int,
let size = Size(rawValue: rawSize) {
self.size = size
} else {
self.size = .Medium
}
}func serialize() -> Any {
return ["cameraRoll": saveToCameraRoll, "size": size.rawValue]
}
}
```#### Saving custom type to NSUserDefaults
`PersistentStore` is the class to save custom types to NSUserDefaults.
Below is the sample of how to use it.```swift
/// Specify a custom type when initializing PersistentStore
let userDefaults = PersistentStore()// Make an instance of CameraConfig
var cs = CameraConfig([:])!// Set
userDefaults.set(cs)
// Get
userDefaults.get()?.size // Medium/// Change the size
cs.size = .Large// Set
userDefaults.set(cs)
// Get
userDefaults.get()?.size // Large
```### Dependency Injection support
NSuserDefaults is not Unit Test friendly because it persistently stores data on file system.
`TypedDefaults` has the types `InMemoryStore` `AnyStore` for Dependency Injection in order to test types which behave differently depending on custom types stored in NSuserDefaults.
`InMemoryStore` adopts `DefaultStoreType` protocol as well as `PersistentStore`.
However, `InMemoryStore` retains custom types only on memory, which is different from `PersistentStore`.
As for `AnyStore`, it is the type to abstract `PersistentStore` and `InMemoryStore`.#### Example
This is the example to use `InMemoryStore` and `AnyStore` instead of `PersistentStore` at Unit Test.
There is a class called `CameraViewController` which inherits UIViewController.
It has a property `config` to retain a custom type saved in NSuserDefaults. To support Dependency Injection, set `AnyStore` as the type of `config`.```
class CameraViewController: UIViewController {
lazy var config: AnyStore = {
let ds = PersistentStore()
return AnyStore(ds)
}()...
}
```Because the type of `config` is not `PersistentStore` but `AnyStore`, it can be replaced with `InMemoryStore` at Unit Test as below.
```
class CameraViewControllerTests: XCTestCase {
var viewController: CameraViewController!override func setUp() {
viewController = CameraViewController()let defaultConfig = CameraConfig([:])!
let ds = InMemoryStore()
ds.set(defaultConfig) //
viewController.config = AnyStore(ds)
}
}
```## Release Notes
See https://github.com/tasanobu/TypedDefaults/releases## License
`TypedDefaults` is released under the MIT license. See LICENSE for details.