Switch to static subscript on `Defaults`
This commit is contained in:
parent
d1e42154f9
commit
90ac6f8802
|
@ -8,7 +8,7 @@ Pod::Spec.new do |s|
|
||||||
s.authors = { 'Sindre Sorhus' => 'sindresorhus@gmail.com' }
|
s.authors = { 'Sindre Sorhus' => 'sindresorhus@gmail.com' }
|
||||||
s.source = { :git => 'https://github.com/sindresorhus/Defaults.git', :tag => "v#{s.version}" }
|
s.source = { :git => 'https://github.com/sindresorhus/Defaults.git', :tag => "v#{s.version}" }
|
||||||
s.source_files = 'Sources/**/*.swift'
|
s.source_files = 'Sources/**/*.swift'
|
||||||
s.swift_version = '5.0'
|
s.swift_version = '5.1'
|
||||||
s.macos.deployment_target = '10.12'
|
s.macos.deployment_target = '10.12'
|
||||||
s.ios.deployment_target = '10.0'
|
s.ios.deployment_target = '10.0'
|
||||||
s.tvos.deployment_target = '10.0'
|
s.tvos.deployment_target = '10.0'
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
52D6D9871BEFF229002C0205 /* Defaults.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D97C1BEFF229002C0205 /* Defaults.framework */; };
|
52D6D9871BEFF229002C0205 /* Defaults.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D97C1BEFF229002C0205 /* Defaults.framework */; };
|
||||||
6614F6E322FC6E1C00B0C9CE /* readme.md in Resources */ = {isa = PBXBuildFile; fileRef = 6614F6E222FC6E1C00B0C9CE /* readme.md */; };
|
|
||||||
8933C7851EB5B820000D00A4 /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* Defaults.swift */; };
|
8933C7851EB5B820000D00A4 /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* Defaults.swift */; };
|
||||||
8933C7861EB5B820000D00A4 /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* Defaults.swift */; };
|
8933C7861EB5B820000D00A4 /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* Defaults.swift */; };
|
||||||
8933C7871EB5B820000D00A4 /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* Defaults.swift */; };
|
8933C7871EB5B820000D00A4 /* Defaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8933C7841EB5B820000D00A4 /* Defaults.swift */; };
|
||||||
|
@ -58,7 +57,7 @@
|
||||||
52D6D9E21BEFFF6E002C0205 /* Defaults.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Defaults.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
52D6D9E21BEFFF6E002C0205 /* Defaults.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Defaults.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
52D6D9F01BEFFFBE002C0205 /* Defaults.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Defaults.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
52D6D9F01BEFFFBE002C0205 /* Defaults.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Defaults.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
52D6DA0F1BF000BD002C0205 /* Defaults.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Defaults.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
52D6DA0F1BF000BD002C0205 /* Defaults.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Defaults.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
6614F6E222FC6E1C00B0C9CE /* readme.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = readme.md; sourceTree = "<group>"; };
|
6614F6E222FC6E1C00B0C9CE /* readme.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; lineEnding = 0; path = readme.md; sourceTree = "<group>"; usesTabs = 1; };
|
||||||
8933C7841EB5B820000D00A4 /* Defaults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = Defaults.swift; sourceTree = "<group>"; usesTabs = 1; };
|
8933C7841EB5B820000D00A4 /* Defaults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = Defaults.swift; sourceTree = "<group>"; usesTabs = 1; };
|
||||||
8933C7891EB5B82A000D00A4 /* DefaultsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = DefaultsTests.swift; sourceTree = "<group>"; usesTabs = 1; };
|
8933C7891EB5B82A000D00A4 /* DefaultsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = DefaultsTests.swift; sourceTree = "<group>"; usesTabs = 1; };
|
||||||
AD2FAA261CD0B6D800659CF4 /* Defaults.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Defaults.plist; sourceTree = "<group>"; };
|
AD2FAA261CD0B6D800659CF4 /* Defaults.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Defaults.plist; sourceTree = "<group>"; };
|
||||||
|
@ -460,7 +459,6 @@
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
6614F6E322FC6E1C00B0C9CE /* readme.md in Resources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -621,7 +619,7 @@
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SWIFT_COMPILATION_MODE = singlefile;
|
SWIFT_COMPILATION_MODE = singlefile;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 4.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
VERSION_INFO_PREFIX = "";
|
VERSION_INFO_PREFIX = "";
|
||||||
|
@ -674,7 +672,7 @@
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.12;
|
MACOSX_DEPLOYMENT_TARGET = 10.12;
|
||||||
MTL_ENABLE_DEBUG_INFO = NO;
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SWIFT_VERSION = 4.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
VALIDATE_PRODUCT = YES;
|
VALIDATE_PRODUCT = YES;
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
|
@ -706,7 +704,6 @@
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_COMPILATION_MODE = singlefile;
|
SWIFT_COMPILATION_MODE = singlefile;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
|
@ -733,7 +730,6 @@
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
@ -754,7 +750,6 @@
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_COMPILATION_MODE = singlefile;
|
SWIFT_COMPILATION_MODE = singlefile;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
|
@ -775,7 +770,6 @@
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
@ -799,7 +793,6 @@
|
||||||
PRODUCT_NAME = Defaults;
|
PRODUCT_NAME = Defaults;
|
||||||
SDKROOT = watchos;
|
SDKROOT = watchos;
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = 4;
|
TARGETED_DEVICE_FAMILY = 4;
|
||||||
WATCHOS_DEPLOYMENT_TARGET = 3.0;
|
WATCHOS_DEPLOYMENT_TARGET = 3.0;
|
||||||
};
|
};
|
||||||
|
@ -827,7 +820,6 @@
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = 4;
|
TARGETED_DEVICE_FAMILY = 4;
|
||||||
WATCHOS_DEPLOYMENT_TARGET = 3.0;
|
WATCHOS_DEPLOYMENT_TARGET = 3.0;
|
||||||
};
|
};
|
||||||
|
@ -853,7 +845,6 @@
|
||||||
PRODUCT_NAME = Defaults;
|
PRODUCT_NAME = Defaults;
|
||||||
SDKROOT = appletvos;
|
SDKROOT = appletvos;
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = 3;
|
TARGETED_DEVICE_FAMILY = 3;
|
||||||
TVOS_DEPLOYMENT_TARGET = 10.0;
|
TVOS_DEPLOYMENT_TARGET = 10.0;
|
||||||
};
|
};
|
||||||
|
@ -881,7 +872,6 @@
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TARGETED_DEVICE_FAMILY = 3;
|
TARGETED_DEVICE_FAMILY = 3;
|
||||||
TVOS_DEPLOYMENT_TARGET = 10.0;
|
TVOS_DEPLOYMENT_TARGET = 10.0;
|
||||||
};
|
};
|
||||||
|
@ -910,7 +900,6 @@
|
||||||
PRODUCT_NAME = Defaults;
|
PRODUCT_NAME = Defaults;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
|
@ -939,7 +928,6 @@
|
||||||
SKIP_INSTALL = YES;
|
SKIP_INSTALL = YES;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
@ -957,7 +945,6 @@
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "com.Defaults.Defaults-macOS-Tests";
|
PRODUCT_BUNDLE_IDENTIFIER = "com.Defaults.Defaults-macOS-Tests";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
|
@ -977,7 +964,6 @@
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
@ -996,7 +982,6 @@
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
SDKROOT = appletvos;
|
SDKROOT = appletvos;
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TVOS_DEPLOYMENT_TARGET = 10.0;
|
TVOS_DEPLOYMENT_TARGET = 10.0;
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
|
@ -1018,7 +1003,6 @@
|
||||||
SDKROOT = appletvos;
|
SDKROOT = appletvos;
|
||||||
SWIFT_COMPILATION_MODE = wholemodule;
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||||
SWIFT_VERSION = 5.0;
|
|
||||||
TVOS_DEPLOYMENT_TARGET = 10.0;
|
TVOS_DEPLOYMENT_TARGET = 10.0;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
|
|
|
@ -14,6 +14,7 @@ public final class Defaults {
|
||||||
public let defaultValue: T
|
public let defaultValue: T
|
||||||
public let suite: UserDefaults
|
public let suite: UserDefaults
|
||||||
|
|
||||||
|
/// Create a defaults key.
|
||||||
public init(_ key: String, default defaultValue: T, suite: UserDefaults = .standard) {
|
public init(_ key: String, default defaultValue: T, suite: UserDefaults = .standard) {
|
||||||
self.name = key
|
self.name = key
|
||||||
self.defaultValue = defaultValue
|
self.defaultValue = defaultValue
|
||||||
|
@ -34,6 +35,7 @@ public final class Defaults {
|
||||||
public let name: String
|
public let name: String
|
||||||
public let suite: UserDefaults
|
public let suite: UserDefaults
|
||||||
|
|
||||||
|
/// Create an optional defaults key.
|
||||||
public init(_ key: String, suite: UserDefaults = .standard) {
|
public init(_ key: String, suite: UserDefaults = .standard) {
|
||||||
self.name = key
|
self.name = key
|
||||||
self.suite = suite
|
self.suite = suite
|
||||||
|
@ -42,65 +44,129 @@ public final class Defaults {
|
||||||
|
|
||||||
fileprivate init() {}
|
fileprivate init() {}
|
||||||
|
|
||||||
public subscript<T: Codable>(key: Defaults.Key<T>) -> T {
|
/// Access a defaults value using a `Defaults.Key`.
|
||||||
get {
|
public static subscript<T: Codable>(key: Defaults.Key<T>) -> T {
|
||||||
return key.suite[key]
|
get { key.suite[key] }
|
||||||
}
|
|
||||||
set {
|
set {
|
||||||
key.suite[key] = newValue
|
key.suite[key] = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public subscript<T: Codable>(key: Defaults.OptionalKey<T>) -> T? {
|
/// Access a defaults value using a `Defaults.OptionalKey`.
|
||||||
get {
|
public static subscript<T: Codable>(key: Defaults.OptionalKey<T>) -> T? {
|
||||||
return key.suite[key]
|
get { key.suite[key] }
|
||||||
}
|
|
||||||
set {
|
set {
|
||||||
key.suite[key] = newValue
|
key.suite[key] = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func clear(suite: UserDefaults = .standard) {
|
/**
|
||||||
for key in suite.dictionaryRepresentation().keys {
|
Reset the given keys back to their default values.
|
||||||
suite.removeObject(forKey: key)
|
|
||||||
}
|
- Parameter keys: Keys to reset.
|
||||||
|
- Parameter suite: `UserDefaults` suite.
|
||||||
|
|
||||||
|
```
|
||||||
|
extension Defaults.Keys {
|
||||||
|
static let isUnicornMode = Key<Bool>("isUnicornMode", default: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reset keys back to their default values.
|
Defaults[.isUnicornMode] = true
|
||||||
/// - Parameter keys: Keys to reset.
|
//=> true
|
||||||
/// - Parameter suite: `UserDefaults` suite.
|
|
||||||
public func reset<T: Codable>(_ keys: Defaults.Key<T>..., suite: UserDefaults = .standard) {
|
Defaults.reset(.isUnicornMode)
|
||||||
|
|
||||||
|
Defaults[.isUnicornMode]
|
||||||
|
//=> false
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
public static func reset<T: Codable>(_ keys: Defaults.Key<T>..., suite: UserDefaults = .standard) {
|
||||||
reset(keys, suite: suite)
|
reset(keys, suite: suite)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reset an array of keys back to their default values.
|
/**
|
||||||
/// - Parameter keys: Keys to reset.
|
Reset the given array of keys back to their default values.
|
||||||
/// - Parameter suite: `UserDefaults` suite.
|
|
||||||
public func reset<T: Codable>(_ keys: [Defaults.Key<T>], suite: UserDefaults = .standard) {
|
- Parameter keys: Keys to reset.
|
||||||
|
- Parameter suite: `UserDefaults` suite.
|
||||||
|
|
||||||
|
```
|
||||||
|
extension Defaults.Keys {
|
||||||
|
static let isUnicornMode = Key<Bool>("isUnicornMode", default: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
Defaults[.isUnicornMode] = true
|
||||||
|
//=> true
|
||||||
|
|
||||||
|
Defaults.reset(.isUnicornMode)
|
||||||
|
|
||||||
|
Defaults[.isUnicornMode]
|
||||||
|
//=> false
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
public static func reset<T: Codable>(_ keys: [Defaults.Key<T>], suite: UserDefaults = .standard) {
|
||||||
for key in keys {
|
for key in keys {
|
||||||
key.suite[key] = key.defaultValue
|
key.suite[key] = key.defaultValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reset optional keys back to `nil`.
|
/**
|
||||||
/// - Parameter keys: Keys to reset.
|
Reset the given optional keys back to `nil`.
|
||||||
/// - Parameter suite: `UserDefaults` suite.
|
|
||||||
public func reset<T: Codable>(_ keys: Defaults.OptionalKey<T>..., suite: UserDefaults = .standard) {
|
- Parameter keys: Keys to reset.
|
||||||
|
- Parameter suite: `UserDefaults` suite.
|
||||||
|
|
||||||
|
```
|
||||||
|
extension Defaults.Keys {
|
||||||
|
static let unicorn = OptionalKey<String>("unicorn")
|
||||||
|
}
|
||||||
|
|
||||||
|
Defaults[.unicorn] = "🦄"
|
||||||
|
|
||||||
|
Defaults.reset(.unicorn)
|
||||||
|
|
||||||
|
Defaults[.unicorn]
|
||||||
|
//=> nil
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
public static func reset<T: Codable>(_ keys: Defaults.OptionalKey<T>..., suite: UserDefaults = .standard) {
|
||||||
reset(keys, suite: suite)
|
reset(keys, suite: suite)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reset an array of optional keys back to `nil`.
|
/**
|
||||||
/// - Parameter keys: Keys to reset.
|
Reset the given array of optional keys back to `nil`.
|
||||||
/// - Parameter suite: `UserDefaults` suite.
|
|
||||||
public func reset<T: Codable>(_ keys: [Defaults.OptionalKey<T>], suite: UserDefaults = .standard) {
|
- Parameter keys: Keys to reset.
|
||||||
|
- Parameter suite: `UserDefaults` suite.
|
||||||
|
|
||||||
|
```
|
||||||
|
extension Defaults.Keys {
|
||||||
|
static let unicorn = OptionalKey<String>("unicorn")
|
||||||
|
}
|
||||||
|
|
||||||
|
Defaults[.unicorn] = "🦄"
|
||||||
|
|
||||||
|
Defaults.reset(.unicorn)
|
||||||
|
|
||||||
|
Defaults[.unicorn]
|
||||||
|
//=> nil
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
public static func reset<T: Codable>(_ keys: [Defaults.OptionalKey<T>], suite: UserDefaults = .standard) {
|
||||||
for key in keys {
|
for key in keys {
|
||||||
key.suite[key] = nil
|
key.suite[key] = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Has to be `defaults` lowercase until Swift supports static subscripts…
|
/**
|
||||||
public let defaults = Defaults()
|
Remove all entries from the `UserDefaults` suite.
|
||||||
|
*/
|
||||||
|
public static func clear(suite: UserDefaults = .standard) {
|
||||||
|
for key in suite.dictionaryRepresentation().keys {
|
||||||
|
suite.removeObject(forKey: key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension UserDefaults {
|
extension UserDefaults {
|
||||||
private func _get<T: Codable>(_ key: String) -> T? {
|
private func _get<T: Codable>(_ key: String) -> T? {
|
||||||
|
@ -147,18 +213,14 @@ extension UserDefaults {
|
||||||
}
|
}
|
||||||
|
|
||||||
public subscript<T: Codable>(key: Defaults.Key<T>) -> T {
|
public subscript<T: Codable>(key: Defaults.Key<T>) -> T {
|
||||||
get {
|
get { _get(key.name) ?? key.defaultValue }
|
||||||
return _get(key.name) ?? key.defaultValue
|
|
||||||
}
|
|
||||||
set {
|
set {
|
||||||
_set(key.name, to: newValue)
|
_set(key.name, to: newValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public subscript<T: Codable>(key: Defaults.OptionalKey<T>) -> T? {
|
public subscript<T: Codable>(key: Defaults.OptionalKey<T>) -> T? {
|
||||||
get {
|
get { _get(key.name) }
|
||||||
return _get(key.name)
|
|
||||||
}
|
|
||||||
set {
|
set {
|
||||||
guard let value = newValue else {
|
guard let value = newValue else {
|
||||||
set(nil, forKey: key.name)
|
set(nil, forKey: key.name)
|
||||||
|
|
|
@ -117,20 +117,20 @@ extension Defaults {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Observe a defaults key
|
Observe a defaults key.
|
||||||
|
|
||||||
```
|
```
|
||||||
extension Defaults.Keys {
|
extension Defaults.Keys {
|
||||||
static let isUnicornMode = Key<Bool>("isUnicornMode", default: false)
|
static let isUnicornMode = Key<Bool>("isUnicornMode", default: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
let observer = defaults.observe(.isUnicornMode) { change in
|
let observer = Defaults.observe(.isUnicornMode) { change in
|
||||||
print(change.newValue)
|
print(change.newValue)
|
||||||
//=> false
|
//=> false
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
*/
|
*/
|
||||||
public func observe<T: Codable>(
|
public static func observe<T: Codable>(
|
||||||
_ key: Defaults.Key<T>,
|
_ key: Defaults.Key<T>,
|
||||||
options: NSKeyValueObservingOptions = [.initial, .old, .new],
|
options: NSKeyValueObservingOptions = [.initial, .old, .new],
|
||||||
handler: @escaping (KeyChange<T>) -> Void
|
handler: @escaping (KeyChange<T>) -> Void
|
||||||
|
@ -145,20 +145,20 @@ extension Defaults {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Observe an optional defaults key
|
Observe an optional defaults key.
|
||||||
|
|
||||||
```
|
```
|
||||||
extension Defaults.Keys {
|
extension Defaults.Keys {
|
||||||
static let isUnicornMode = OptionalKey<Bool>("isUnicornMode")
|
static let isUnicornMode = OptionalKey<Bool>("isUnicornMode")
|
||||||
}
|
}
|
||||||
|
|
||||||
let observer = defaults.observe(.isUnicornMode) { change in
|
let observer = Defaults.observe(.isUnicornMode) { change in
|
||||||
print(change.newValue)
|
print(change.newValue)
|
||||||
//=> Optional(nil)
|
//=> Optional(nil)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
*/
|
*/
|
||||||
public func observe<T: Codable>(
|
public static func observe<T: Codable>(
|
||||||
_ key: Defaults.OptionalKey<T>,
|
_ key: Defaults.OptionalKey<T>,
|
||||||
options: NSKeyValueObservingOptions = [.initial, .old, .new],
|
options: NSKeyValueObservingOptions = [.initial, .old, .new],
|
||||||
handler: @escaping (OptionalKeyChange<T>) -> Void
|
handler: @escaping (OptionalKeyChange<T>) -> Void
|
||||||
|
|
|
@ -24,30 +24,30 @@ extension Defaults.Keys {
|
||||||
final class DefaultsTests: XCTestCase {
|
final class DefaultsTests: XCTestCase {
|
||||||
override func setUp() {
|
override func setUp() {
|
||||||
super.setUp()
|
super.setUp()
|
||||||
defaults.clear()
|
Defaults.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tearDown() {
|
override func tearDown() {
|
||||||
super.setUp()
|
super.setUp()
|
||||||
defaults.clear()
|
Defaults.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
func testKey() {
|
func testKey() {
|
||||||
let key = Defaults.Key<Bool>("independentKey", default: false)
|
let key = Defaults.Key<Bool>("independentKey", default: false)
|
||||||
XCTAssertFalse(defaults[key])
|
XCTAssertFalse(Defaults[key])
|
||||||
defaults[key] = true
|
Defaults[key] = true
|
||||||
XCTAssertTrue(defaults[key])
|
XCTAssertTrue(Defaults[key])
|
||||||
}
|
}
|
||||||
|
|
||||||
func testOptionalKey() {
|
func testOptionalKey() {
|
||||||
let key = Defaults.OptionalKey<Bool>("independentOptionalKey")
|
let key = Defaults.OptionalKey<Bool>("independentOptionalKey")
|
||||||
XCTAssertNil(defaults[key])
|
XCTAssertNil(Defaults[key])
|
||||||
defaults[key] = true
|
Defaults[key] = true
|
||||||
XCTAssertTrue(defaults[key]!)
|
XCTAssertTrue(Defaults[key]!)
|
||||||
defaults[key] = nil
|
Defaults[key] = nil
|
||||||
XCTAssertNil(defaults[key])
|
XCTAssertNil(Defaults[key])
|
||||||
defaults[key] = false
|
Defaults[key] = false
|
||||||
XCTAssertFalse(defaults[key]!)
|
XCTAssertFalse(Defaults[key]!)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testKeyRegistersDefault() {
|
func testKeyRegistersDefault() {
|
||||||
|
@ -56,7 +56,7 @@ final class DefaultsTests: XCTestCase {
|
||||||
_ = Defaults.Key<Bool>(keyName, default: true)
|
_ = Defaults.Key<Bool>(keyName, default: true)
|
||||||
XCTAssertEqual(UserDefaults.standard.bool(forKey: keyName), true)
|
XCTAssertEqual(UserDefaults.standard.bool(forKey: keyName), true)
|
||||||
|
|
||||||
// Test that it works with multiple keys with defaults
|
// Test that it works with multiple keys with Defaults.
|
||||||
let keyName2 = "registersDefault2"
|
let keyName2 = "registersDefault2"
|
||||||
_ = Defaults.Key<String>(keyName2, default: keyName2)
|
_ = Defaults.Key<String>(keyName2, default: keyName2)
|
||||||
XCTAssertEqual(UserDefaults.standard.string(forKey: keyName2), keyName2)
|
XCTAssertEqual(UserDefaults.standard.string(forKey: keyName2), keyName2)
|
||||||
|
@ -70,56 +70,56 @@ final class DefaultsTests: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testKeys() {
|
func testKeys() {
|
||||||
XCTAssertFalse(defaults[.key])
|
XCTAssertFalse(Defaults[.key])
|
||||||
defaults[.key] = true
|
Defaults[.key] = true
|
||||||
XCTAssertTrue(defaults[.key])
|
XCTAssertTrue(Defaults[.key])
|
||||||
}
|
}
|
||||||
|
|
||||||
func testUrlType() {
|
func testUrlType() {
|
||||||
XCTAssertEqual(defaults[.url], fixtureURL)
|
XCTAssertEqual(Defaults[.url], fixtureURL)
|
||||||
|
|
||||||
let newUrl = URL(string: "https://twitter.com")!
|
let newUrl = URL(string: "https://twitter.com")!
|
||||||
defaults[.url] = newUrl
|
Defaults[.url] = newUrl
|
||||||
XCTAssertEqual(defaults[.url], newUrl)
|
XCTAssertEqual(Defaults[.url], newUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testEnumType() {
|
func testEnumType() {
|
||||||
XCTAssertEqual(defaults[.enum], FixtureEnum.oneHour)
|
XCTAssertEqual(Defaults[.enum], FixtureEnum.oneHour)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDataType() {
|
func testDataType() {
|
||||||
XCTAssertEqual(defaults[.data], Data([]))
|
XCTAssertEqual(Defaults[.data], Data([]))
|
||||||
|
|
||||||
let newData = Data([0xFF])
|
let newData = Data([0xFF])
|
||||||
defaults[.data] = newData
|
Defaults[.data] = newData
|
||||||
XCTAssertEqual(defaults[.data], newData)
|
XCTAssertEqual(Defaults[.data], newData)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testDateType() {
|
func testDateType() {
|
||||||
XCTAssertEqual(defaults[.date], fixtureDate)
|
XCTAssertEqual(Defaults[.date], fixtureDate)
|
||||||
|
|
||||||
let newDate = Date()
|
let newDate = Date()
|
||||||
defaults[.date] = newDate
|
Defaults[.date] = newDate
|
||||||
XCTAssertEqual(defaults[.date], newDate)
|
XCTAssertEqual(Defaults[.date], newDate)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testClear() {
|
func testClear() {
|
||||||
let key = Defaults.Key<Bool>("clear", default: false)
|
let key = Defaults.Key<Bool>("clear", default: false)
|
||||||
defaults[key] = true
|
Defaults[key] = true
|
||||||
XCTAssertTrue(defaults[key])
|
XCTAssertTrue(Defaults[key])
|
||||||
defaults.clear()
|
Defaults.clear()
|
||||||
XCTAssertFalse(defaults[key])
|
XCTAssertFalse(Defaults[key])
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCustomSuite() {
|
func testCustomSuite() {
|
||||||
let customSuite = UserDefaults(suiteName: "com.sindresorhus.customSuite")!
|
let customSuite = UserDefaults(suiteName: "com.sindresorhus.customSuite")!
|
||||||
let key = Defaults.Key<Bool>("customSuite", default: false, suite: customSuite)
|
let key = Defaults.Key<Bool>("customSuite", default: false, suite: customSuite)
|
||||||
XCTAssertFalse(customSuite[key])
|
XCTAssertFalse(customSuite[key])
|
||||||
XCTAssertFalse(defaults[key])
|
XCTAssertFalse(Defaults[key])
|
||||||
defaults[key] = true
|
Defaults[key] = true
|
||||||
XCTAssertTrue(customSuite[key])
|
XCTAssertTrue(customSuite[key])
|
||||||
XCTAssertTrue(defaults[key])
|
XCTAssertTrue(Defaults[key])
|
||||||
defaults.clear(suite: customSuite)
|
Defaults.clear(suite: customSuite)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testObserveKey() {
|
func testObserveKey() {
|
||||||
|
@ -127,14 +127,14 @@ final class DefaultsTests: XCTestCase {
|
||||||
let expect = expectation(description: "Observation closure being called")
|
let expect = expectation(description: "Observation closure being called")
|
||||||
|
|
||||||
var observation: DefaultsObservation!
|
var observation: DefaultsObservation!
|
||||||
observation = defaults.observe(key, options: [.old, .new]) { change in
|
observation = Defaults.observe(key, options: [.old, .new]) { change in
|
||||||
XCTAssertFalse(change.oldValue)
|
XCTAssertFalse(change.oldValue)
|
||||||
XCTAssertTrue(change.newValue)
|
XCTAssertTrue(change.newValue)
|
||||||
observation.invalidate()
|
observation.invalidate()
|
||||||
expect.fulfill()
|
expect.fulfill()
|
||||||
}
|
}
|
||||||
|
|
||||||
defaults[key] = true
|
Defaults[key] = true
|
||||||
|
|
||||||
waitForExpectations(timeout: 10)
|
waitForExpectations(timeout: 10)
|
||||||
}
|
}
|
||||||
|
@ -144,14 +144,14 @@ final class DefaultsTests: XCTestCase {
|
||||||
let expect = expectation(description: "Observation closure being called")
|
let expect = expectation(description: "Observation closure being called")
|
||||||
|
|
||||||
var observation: DefaultsObservation!
|
var observation: DefaultsObservation!
|
||||||
observation = defaults.observe(key, options: [.old, .new]) { change in
|
observation = Defaults.observe(key, options: [.old, .new]) { change in
|
||||||
XCTAssertNil(change.oldValue)
|
XCTAssertNil(change.oldValue)
|
||||||
XCTAssertTrue(change.newValue!)
|
XCTAssertTrue(change.newValue!)
|
||||||
observation.invalidate()
|
observation.invalidate()
|
||||||
expect.fulfill()
|
expect.fulfill()
|
||||||
}
|
}
|
||||||
|
|
||||||
defaults[key] = true
|
Defaults[key] = true
|
||||||
|
|
||||||
waitForExpectations(timeout: 10)
|
waitForExpectations(timeout: 10)
|
||||||
}
|
}
|
||||||
|
@ -163,14 +163,14 @@ final class DefaultsTests: XCTestCase {
|
||||||
let expect = expectation(description: "Observation closure being called")
|
let expect = expectation(description: "Observation closure being called")
|
||||||
|
|
||||||
var observation: DefaultsObservation!
|
var observation: DefaultsObservation!
|
||||||
observation = defaults.observe(key, options: [.old, .new]) { change in
|
observation = Defaults.observe(key, options: [.old, .new]) { change in
|
||||||
XCTAssertEqual(change.oldValue, fixtureURL)
|
XCTAssertEqual(change.oldValue, fixtureURL)
|
||||||
XCTAssertEqual(change.newValue, fixtureURL2)
|
XCTAssertEqual(change.newValue, fixtureURL2)
|
||||||
observation.invalidate()
|
observation.invalidate()
|
||||||
expect.fulfill()
|
expect.fulfill()
|
||||||
}
|
}
|
||||||
|
|
||||||
defaults[key] = fixtureURL2
|
Defaults[key] = fixtureURL2
|
||||||
|
|
||||||
waitForExpectations(timeout: 10)
|
waitForExpectations(timeout: 10)
|
||||||
}
|
}
|
||||||
|
@ -180,14 +180,14 @@ final class DefaultsTests: XCTestCase {
|
||||||
let expect = expectation(description: "Observation closure being called")
|
let expect = expectation(description: "Observation closure being called")
|
||||||
|
|
||||||
var observation: DefaultsObservation!
|
var observation: DefaultsObservation!
|
||||||
observation = defaults.observe(key, options: [.old, .new]) { change in
|
observation = Defaults.observe(key, options: [.old, .new]) { change in
|
||||||
XCTAssertEqual(change.oldValue, .oneHour)
|
XCTAssertEqual(change.oldValue, .oneHour)
|
||||||
XCTAssertEqual(change.newValue, .tenMinutes)
|
XCTAssertEqual(change.newValue, .tenMinutes)
|
||||||
observation.invalidate()
|
observation.invalidate()
|
||||||
expect.fulfill()
|
expect.fulfill()
|
||||||
}
|
}
|
||||||
|
|
||||||
defaults[key] = .tenMinutes
|
Defaults[key] = .tenMinutes
|
||||||
|
|
||||||
waitForExpectations(timeout: 10)
|
waitForExpectations(timeout: 10)
|
||||||
}
|
}
|
||||||
|
@ -199,11 +199,11 @@ final class DefaultsTests: XCTestCase {
|
||||||
let newString2 = "bar2"
|
let newString2 = "bar2"
|
||||||
let key1 = Defaults.Key<String>("key1", default: defaultString1)
|
let key1 = Defaults.Key<String>("key1", default: defaultString1)
|
||||||
let key2 = Defaults.Key<String>("key2", default: defaultString2)
|
let key2 = Defaults.Key<String>("key2", default: defaultString2)
|
||||||
defaults[key1] = newString1
|
Defaults[key1] = newString1
|
||||||
defaults[key2] = newString2
|
Defaults[key2] = newString2
|
||||||
defaults.reset(key1)
|
Defaults.reset(key1)
|
||||||
XCTAssertEqual(defaults[key1], defaultString1)
|
XCTAssertEqual(Defaults[key1], defaultString1)
|
||||||
XCTAssertEqual(defaults[key2], newString2)
|
XCTAssertEqual(Defaults[key2], newString2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testResetKeyArray() {
|
func testResetKeyArray() {
|
||||||
|
@ -216,13 +216,13 @@ final class DefaultsTests: XCTestCase {
|
||||||
let key1 = Defaults.Key<String>("akey1", default: defaultString1)
|
let key1 = Defaults.Key<String>("akey1", default: defaultString1)
|
||||||
let key2 = Defaults.Key<String>("akey2", default: defaultString2)
|
let key2 = Defaults.Key<String>("akey2", default: defaultString2)
|
||||||
let key3 = Defaults.Key<String>("akey3", default: defaultString3)
|
let key3 = Defaults.Key<String>("akey3", default: defaultString3)
|
||||||
defaults[key1] = newString1
|
Defaults[key1] = newString1
|
||||||
defaults[key2] = newString2
|
Defaults[key2] = newString2
|
||||||
defaults[key3] = newString3
|
Defaults[key3] = newString3
|
||||||
defaults.reset(key1, key2)
|
Defaults.reset(key1, key2)
|
||||||
XCTAssertEqual(defaults[key1], defaultString1)
|
XCTAssertEqual(Defaults[key1], defaultString1)
|
||||||
XCTAssertEqual(defaults[key2], defaultString2)
|
XCTAssertEqual(Defaults[key2], defaultString2)
|
||||||
XCTAssertEqual(defaults[key3], newString3)
|
XCTAssertEqual(Defaults[key3], newString3)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testResetOptionalKey() {
|
func testResetOptionalKey() {
|
||||||
|
@ -230,11 +230,11 @@ final class DefaultsTests: XCTestCase {
|
||||||
let newString2 = "bar2"
|
let newString2 = "bar2"
|
||||||
let key1 = Defaults.OptionalKey<String>("optionalKey1")
|
let key1 = Defaults.OptionalKey<String>("optionalKey1")
|
||||||
let key2 = Defaults.OptionalKey<String>("optionalKey2")
|
let key2 = Defaults.OptionalKey<String>("optionalKey2")
|
||||||
defaults[key1] = newString1
|
Defaults[key1] = newString1
|
||||||
defaults[key2] = newString2
|
Defaults[key2] = newString2
|
||||||
defaults.reset(key1)
|
Defaults.reset(key1)
|
||||||
XCTAssertEqual(defaults[key1], nil)
|
XCTAssertEqual(Defaults[key1], nil)
|
||||||
XCTAssertEqual(defaults[key2], newString2)
|
XCTAssertEqual(Defaults[key2], newString2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testResetOptionalKeyArray() {
|
func testResetOptionalKeyArray() {
|
||||||
|
@ -244,12 +244,12 @@ final class DefaultsTests: XCTestCase {
|
||||||
let key1 = Defaults.OptionalKey<String>("aoptionalKey1")
|
let key1 = Defaults.OptionalKey<String>("aoptionalKey1")
|
||||||
let key2 = Defaults.OptionalKey<String>("aoptionalKey2")
|
let key2 = Defaults.OptionalKey<String>("aoptionalKey2")
|
||||||
let key3 = Defaults.OptionalKey<String>("aoptionalKey3")
|
let key3 = Defaults.OptionalKey<String>("aoptionalKey3")
|
||||||
defaults[key1] = newString1
|
Defaults[key1] = newString1
|
||||||
defaults[key2] = newString2
|
Defaults[key2] = newString2
|
||||||
defaults[key3] = newString3
|
Defaults[key3] = newString3
|
||||||
defaults.reset(key1, key2)
|
Defaults.reset(key1, key2)
|
||||||
XCTAssertEqual(defaults[key1], nil)
|
XCTAssertEqual(Defaults[key1], nil)
|
||||||
XCTAssertEqual(defaults[key2], nil)
|
XCTAssertEqual(Defaults[key2], nil)
|
||||||
XCTAssertEqual(defaults[key3], newString3)
|
XCTAssertEqual(Defaults[key3], newString3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
59
readme.md
59
readme.md
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
> Swifty and modern [UserDefaults](https://developer.apple.com/documentation/foundation/userdefaults)
|
> Swifty and modern [UserDefaults](https://developer.apple.com/documentation/foundation/userdefaults)
|
||||||
|
|
||||||
This package is used in production by the [Lungo](https://sindresorhus.com/lungo), [Battery Indicator](https://sindresorhus.com/battery-indicator), and [HEIC Converter](https://sindresorhus.com/heic-converter) app.
|
This package is used in production by the [Gifski](https://github.com/sindresorhus/Gifski), [Lungo](https://sindresorhus.com/lungo), [Battery Indicator](https://sindresorhus.com/battery-indicator), and [HEIC Converter](https://sindresorhus.com/heic-converter) app.
|
||||||
|
|
||||||
|
|
||||||
## Highlights
|
## Highlights
|
||||||
|
@ -58,19 +58,19 @@ extension Defaults.Keys {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
You can then access it as a subscript on the `defaults` global (note lowercase):
|
You can then access it as a subscript on the `Defaults` global:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
defaults[.quality]
|
Defaults[.quality]
|
||||||
//=> 0.8
|
//=> 0.8
|
||||||
|
|
||||||
defaults[.quality] = 0.5
|
Defaults[.quality] = 0.5
|
||||||
//=> 0.5
|
//=> 0.5
|
||||||
|
|
||||||
defaults[.quality] += 0.1
|
Defaults[.quality] += 0.1
|
||||||
//=> 0.6
|
//=> 0.6
|
||||||
|
|
||||||
defaults[.quality] = "🦄"
|
Defaults[.quality] = "🦄"
|
||||||
//=> [Cannot assign value of type 'String' to type 'Double']
|
//=> [Cannot assign value of type 'String' to type 'Double']
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ extension Defaults.Keys {
|
||||||
static let name = OptionalKey<Double>("name")
|
static let name = OptionalKey<Double>("name")
|
||||||
}
|
}
|
||||||
|
|
||||||
if let name = defaults[.name] {
|
if let name = Defaults[.name] {
|
||||||
print(name)
|
print(name)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -101,7 +101,7 @@ extension Defaults.Keys {
|
||||||
static let defaultDuration = Key<DurationKeys>("defaultDuration", default: .oneHour)
|
static let defaultDuration = Key<DurationKeys>("defaultDuration", default: .oneHour)
|
||||||
}
|
}
|
||||||
|
|
||||||
defaults[.defaultDuration].rawValue
|
Defaults[.defaultDuration].rawValue
|
||||||
//=> "1 Hour"
|
//=> "1 Hour"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ extension Defaults.Keys {
|
||||||
static let isUnicorn = Key<Bool>("isUnicorn", default: true, suite: extensionDefaults)
|
static let isUnicorn = Key<Bool>("isUnicorn", default: true, suite: extensionDefaults)
|
||||||
}
|
}
|
||||||
|
|
||||||
defaults[.isUnicorn]
|
Defaults[.isUnicorn]
|
||||||
//=> true
|
//=> true
|
||||||
|
|
||||||
// Or
|
// Or
|
||||||
|
@ -143,7 +143,7 @@ You are not required to attach keys to `Defaults.Keys`.
|
||||||
```swift
|
```swift
|
||||||
let isUnicorn = Defaults.Key<Bool>("isUnicorn", default: true)
|
let isUnicorn = Defaults.Key<Bool>("isUnicorn", default: true)
|
||||||
|
|
||||||
defaults[isUnicorn]
|
Defaults[isUnicorn]
|
||||||
//=> true
|
//=> true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ extension Defaults.Keys {
|
||||||
static let isUnicornMode = Key<Bool>("isUnicornMode", default: false)
|
static let isUnicornMode = Key<Bool>("isUnicornMode", default: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
let observer = defaults.observe(.isUnicornMode) { change in
|
let observer = Defaults.observe(.isUnicornMode) { change in
|
||||||
// Initial event
|
// Initial event
|
||||||
print(change.oldValue)
|
print(change.oldValue)
|
||||||
//=> false
|
//=> false
|
||||||
|
@ -168,7 +168,7 @@ let observer = defaults.observe(.isUnicornMode) { change in
|
||||||
//=> true
|
//=> true
|
||||||
}
|
}
|
||||||
|
|
||||||
defaults[.isUnicornMode] = true
|
Defaults[.isUnicornMode] = true
|
||||||
```
|
```
|
||||||
|
|
||||||
In contrast to the native `UserDefaults` key observation, here you receive a strongly-typed change object.
|
In contrast to the native `UserDefaults` key observation, here you receive a strongly-typed change object.
|
||||||
|
@ -180,12 +180,12 @@ extension Defaults.Keys {
|
||||||
static let isUnicornMode = Key<Bool>("isUnicornMode", default: false)
|
static let isUnicornMode = Key<Bool>("isUnicornMode", default: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
defaults[.isUnicornMode] = true
|
Defaults[.isUnicornMode] = true
|
||||||
//=> true
|
//=> true
|
||||||
|
|
||||||
defaults.reset(.isUnicornMode)
|
Defaults.reset(.isUnicornMode)
|
||||||
|
|
||||||
defaults[.isUnicornMode]
|
Defaults[.isUnicornMode]
|
||||||
//=> false
|
//=> false
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ print(UserDefaults.standard.bool(forKey: isUnicornMode.name))
|
||||||
|
|
||||||
## API
|
## API
|
||||||
|
|
||||||
### `let defaults = Defaults()`
|
### `Defaults`
|
||||||
|
|
||||||
#### `Defaults.Keys`
|
#### `Defaults.Keys`
|
||||||
|
|
||||||
|
@ -225,7 +225,7 @@ Type: `class`
|
||||||
|
|
||||||
Create a key with a default value.
|
Create a key with a default value.
|
||||||
|
|
||||||
The default value is written to the actual `UserDefaults` and can be used elsewhere. For example, with Interface Builder binding.
|
The default value is written to the actual `UserDefaults` and can be used elsewhere. For example, with a Interface Builder binding.
|
||||||
|
|
||||||
#### `Defaults.OptionalKey` *(alias `Defaults.Keys.OptionalKey`)*
|
#### `Defaults.OptionalKey` *(alias `Defaults.Keys.OptionalKey`)*
|
||||||
|
|
||||||
|
@ -237,20 +237,23 @@ Type: `class`
|
||||||
|
|
||||||
Create a key with an optional value.
|
Create a key with an optional value.
|
||||||
|
|
||||||
#### `Defaults#clear`
|
#### `Defaults.reset`
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
clear(suite: UserDefaults = .standard)
|
Defaults.reset<T: Codable>(_ keys: Defaults.Key<T>..., suite: UserDefaults = .standard)
|
||||||
|
Defaults.reset<T: Codable>(_ keys: [Defaults.Key<T>], suite: UserDefaults = .standard)
|
||||||
|
Defaults.reset<T: Codable>(_ keys: Defaults.OptionalKey<T>..., suite: UserDefaults = .standard)
|
||||||
|
Defaults.reset<T: Codable>(_ keys: [Defaults.OptionalKey<T>], suite: UserDefaults = .standard)
|
||||||
```
|
```
|
||||||
|
|
||||||
Type: `func`
|
Type: `func`
|
||||||
|
|
||||||
Clear the user defaults.
|
Reset the given keys back to their default values.
|
||||||
|
|
||||||
#### `Defaults#observe`
|
#### `Defaults.observe`
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
observe<T: Codable>(
|
Defaults.observe<T: Codable>(
|
||||||
_ key: Defaults.Key<T>,
|
_ key: Defaults.Key<T>,
|
||||||
options: NSKeyValueObservingOptions = [.initial, .old, .new],
|
options: NSKeyValueObservingOptions = [.initial, .old, .new],
|
||||||
handler: @escaping (KeyChange<T>) -> Void
|
handler: @escaping (KeyChange<T>) -> Void
|
||||||
|
@ -258,7 +261,7 @@ observe<T: Codable>(
|
||||||
```
|
```
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
observe<T: Codable>(
|
Defaults.observe<T: Codable>(
|
||||||
_ key: Defaults.OptionalKey<T>,
|
_ key: Defaults.OptionalKey<T>,
|
||||||
options: NSKeyValueObservingOptions = [.initial, .old, .new],
|
options: NSKeyValueObservingOptions = [.initial, .old, .new],
|
||||||
handler: @escaping (OptionalKeyChange<T>) -> Void
|
handler: @escaping (OptionalKeyChange<T>) -> Void
|
||||||
|
@ -271,6 +274,16 @@ Observe changes to a key or an optional key.
|
||||||
|
|
||||||
By default, it will also trigger an initial event on creation. This can be useful for setting default values on controls. You can override this behavior with the `options` argument.
|
By default, it will also trigger an initial event on creation. This can be useful for setting default values on controls. You can override this behavior with the `options` argument.
|
||||||
|
|
||||||
|
#### `Defaults.clear`
|
||||||
|
|
||||||
|
```swift
|
||||||
|
Defaults.clear(suite: UserDefaults = .standard)
|
||||||
|
```
|
||||||
|
|
||||||
|
Type: `func`
|
||||||
|
|
||||||
|
Clear the user defaults.
|
||||||
|
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue