The simplest UserDefaults wrapper PropertyDefaults lets you guarantee unsafe literal-based UserDefaults keys and values and guarantee them. Codable type support. This project is hard fork with entirely different approaches from DefaultsKit
Installation
Usage
Instantiate, or get a shared
instance of Defaults
let defaults = Defaults() // or Defaults.shared
Features
- Swift 4 Codable Support
- Key-Value-Type-safety - Using pre-defined Swift property instead of String literal.
- Restriction for using only Protocol.
- Permission control with Protocol
- Integration with Keychain Access as the same interface.
Key-Safety Property Definition
PropertyDefaults supports only protocol expansion pattern that is focusing on syntax-driven key value handling, therefore perfect safe custom properties with Swift.
An example to use with basic Codable types:
extension Defaults: PropertyDefaults {
public var autoStringProperty: String? {
set{ set(newValue) } get{ return get() }
}
public var autoDateProperty: Date? {
set{ set(newValue) } get{ return get() }
}
}
So you can use Defaults like this:
var sharedDefaults = Defaults()
sharedDefaults.autoStringProperty = "the new value will persist in shared scope"
Defaults.shared.autoStringProperty = "the new value will persist in shared scope"
// sharedDefaults.autoStringProperty == Defaults.shared.autoStringProperty
var localDefaults = Defaults(suiteName:"local")
localDefaults.autoStringProperty = "the new value will persist in local scope"
// localDefaults.autoStringProperty != Defaults.shared.autoStringProperty
Directly save/load as Codable type
public struct CustomValueType: Codable{
var key:String = "value"
}
extension Defaults: PropertyDefaults {
// default value with 'or'
public var autoStringPropertyWithDefaultValue: String? {
set{ set(newValue) } get{ return get(or:"default string value") }
}
// non-optional - must define the default value with the keyword 'or'
public var autoCustomNonOptionalProperty: CustomValueType {
set{ set(newValue) } get{ return get(or: CustomValueType()) }
}
// optional with/without setter default value
public var autoCustomOptionalProperty: CustomValueType? {
set{ set(newValue) } get{ return get() }
}
public var autoCustomOptionalPropertySetterDefaultValue: CustomValueType? {
set{ set(newValue, or: CustomValueType()) } get{ return get() }
}
}
With this pattern, as you know, you also can control access permission with protocol. It means you can use 'private' or 'fileprivate' defaults access.
// MyFile.swift
fileprivate protocol PrivateDefaultKeysInThisSwiftFile:PropertyDefaults{
var filePrivateValue: String? {set get}
}
extension Defaults: PrivateDefaultKeysInThisSwiftFile {
public var filePrivateValue: String? {
set{ set(newValue) } get{ return get() }
}
}
// Can access - 👌
Defaults.shared.filePrivateValue
// MyOtherFile.swift
// Not able to access - ❌
Defaults.shared.filePrivateValue