TSUD (pronounced "tsud") stands for Type-Safe User Defaults and is an experimental Swifty wrapper around NSUserDefaults
.
Public domain. Do what you feel like. Credit is appreciated but not required.
To declare a key, write a struct
conforming to the TSUD
protocol. Inside, implement a single static
property called defaultValue
which contains the value to be returned if UserDefaults
doesn't contain a value:
struct fontSize: TSUD {
static let defaultValue = 12.0
}
To read or write the value, use the value
property on the struct
:
let font = NSFont.systemFont(ofSize: fontSize.value)
fontSize.value = 14.0
Since value
is just a property, you can do disturbing and unnatural things like +=
to it.
fontSize.value += 5.0
If you want to be able to detect the lack of a value and handle it specially rather than getting a default value, declare defaultValue
to be optional and set it to nil
:
struct username: TSUD {
static let defaultValue: String? = nil
}
Then use it like any other optional:
if let username = username.value {
field.string = username
} else {
username.value = promptForUsername()
}
By default, TSUD
types correspond to a UserDefaults
key matching their type name. These examples would be stored under "fontSize"
and "username"
. If you need to override this (for example, because you want to access a key that has a space in it, or you don't like the key's capitalization in your code), implement the stringKey
property:
struct hasWidgets: TSUD {
static let defaultValue = false
static let stringKey = "Has Widgets"
}
Arbitrary Codable
types are supported. They are encoded as property list objects:
struct Person: Codable {
var name: String
var quest: String
var age: Int
}
struct testPerson: TSUD {
static let defaultValue: Person? = nil
}
If you prefer, you can also use methods to get and set the value:
if hasWidgets.get() {
hasWidgets.set(false)
}
These methods allow you to specify the UserDefaults
object to work with, in the unlikely event that you want to work with something other than UserDefaults.standard
:
let otherDefaults = UserDefaults(suitName: "...")!
if hasWidgets.get(otherDefaults) {
// That other thing has widgets!
}
If you want to access the value in another UserDefaults
instance as a mutable value, there's a subscript which takes a UserDefaults
instance and provides the value. Unfortunately, Swift doesn't allow static
subscripts, so you have to instantiate the key type:
fontSize()[otherDefaults] += 10.0