Get rid of `OptionalKey`
This commit is contained in:
parent
3275717838
commit
b2fdee2055
|
@ -1,3 +1,3 @@
|
|||
language: swift
|
||||
osx_image: xcode11.3
|
||||
osx_image: xcode11.4
|
||||
script: xcodebuild test -project Defaults.xcodeproj -scheme Defaults-macOS
|
||||
|
|
|
@ -8,7 +8,7 @@ Pod::Spec.new do |s|
|
|||
s.authors = { 'Sindre Sorhus' => 'sindresorhus@gmail.com' }
|
||||
s.source = { :git => 'https://github.com/sindresorhus/Defaults.git', :tag => "v#{s.version}" }
|
||||
s.source_files = 'Sources/**/*.swift'
|
||||
s.swift_version = '5.1'
|
||||
s.swift_version = '5.2'
|
||||
s.macos.deployment_target = '10.12'
|
||||
s.ios.deployment_target = '10.0'
|
||||
s.tvos.deployment_target = '10.0'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// swift-tools-version:5.1
|
||||
// swift-tools-version:5.2
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
|
|
|
@ -8,8 +8,6 @@ public final class Defaults {
|
|||
@available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, iOSApplicationExtension 11.0, macOSApplicationExtension 10.13, tvOSApplicationExtension 11.0, watchOSApplicationExtension 4.0, *)
|
||||
public typealias NSSecureCodingKey = Defaults.NSSecureCodingKey
|
||||
|
||||
public typealias OptionalKey = Defaults.OptionalKey
|
||||
|
||||
@available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, iOSApplicationExtension 11.0, macOSApplicationExtension 10.13, tvOSApplicationExtension 11.0, watchOSApplicationExtension 4.0, *)
|
||||
public typealias NSSecureCodingOptionalKey = Defaults.NSSecureCodingOptionalKey
|
||||
|
||||
|
@ -29,6 +27,10 @@ public final class Defaults {
|
|||
|
||||
super.init()
|
||||
|
||||
if (defaultValue as? _DefaultsOptionalType)?.isNil == true {
|
||||
return
|
||||
}
|
||||
|
||||
// Sets the default value in the actual UserDefaults, so it can be used in other contexts, like binding.
|
||||
if UserDefaults.isNativelySupportedType(Value.self) {
|
||||
suite.register(defaults: [key: defaultValue])
|
||||
|
@ -52,6 +54,10 @@ public final class Defaults {
|
|||
|
||||
super.init()
|
||||
|
||||
if (defaultValue as? _DefaultsOptionalType)?.isNil == true {
|
||||
return
|
||||
}
|
||||
|
||||
// Sets the default value in the actual UserDefaults, so it can be used in other contexts, like binding.
|
||||
if UserDefaults.isNativelySupportedType(Value.self) {
|
||||
suite.register(defaults: [key: defaultValue])
|
||||
|
@ -61,17 +67,6 @@ public final class Defaults {
|
|||
}
|
||||
}
|
||||
|
||||
public final class OptionalKey<Value: Codable>: Keys {
|
||||
public let name: String
|
||||
public let suite: UserDefaults
|
||||
|
||||
/// Create an optional defaults key.
|
||||
public init(_ key: String, suite: UserDefaults = .standard) {
|
||||
self.name = key
|
||||
self.suite = suite
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, iOSApplicationExtension 11.0, macOSApplicationExtension 10.13, tvOSApplicationExtension 11.0, watchOSApplicationExtension 4.0, *)
|
||||
public final class NSSecureCodingOptionalKey<Value: NSSecureCoding>: Keys {
|
||||
public let name: String
|
||||
|
@ -103,15 +98,7 @@ public final class Defaults {
|
|||
}
|
||||
}
|
||||
|
||||
/// Access a defaults value using a `Defaults.OptionalKey`.
|
||||
public static subscript<Value: Codable>(key: OptionalKey<Value>) -> Value? {
|
||||
get { key.suite[key] }
|
||||
set {
|
||||
key.suite[key] = newValue
|
||||
}
|
||||
}
|
||||
|
||||
/// Access a defaults value using a `Defaults.OptionalKey`.
|
||||
/// Access a defaults value using a `Defaults.NSSecureCodingOptionalKey`.
|
||||
@available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, iOSApplicationExtension 11.0, macOSApplicationExtension 10.13, tvOSApplicationExtension 11.0, watchOSApplicationExtension 4.0, *)
|
||||
public static subscript<Value: NSSecureCoding>(key: NSSecureCodingOptionalKey<Value>) -> Value? {
|
||||
get { key.suite[key] }
|
||||
|
@ -193,29 +180,6 @@ public final class Defaults {
|
|||
key.suite[key] = key.defaultValue
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Reset the given optional keys back to `nil`.
|
||||
|
||||
- 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<Value: Codable>(_ keys: OptionalKey<Value>..., suite: UserDefaults = .standard) {
|
||||
reset(keys, suite: suite)
|
||||
}
|
||||
|
||||
/**
|
||||
Reset the given optional keys back to `nil`.
|
||||
|
@ -228,31 +192,6 @@ public final class Defaults {
|
|||
public static func reset<Value: NSSecureCoding>(_ keys: NSSecureCodingOptionalKey<Value>..., suite: UserDefaults = .standard) {
|
||||
reset(keys, suite: suite)
|
||||
}
|
||||
|
||||
/**
|
||||
Reset the given array of optional keys back to `nil`.
|
||||
|
||||
- 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<Value: Codable>(_ keys: [OptionalKey<Value>], suite: UserDefaults = .standard) {
|
||||
for key in keys {
|
||||
key.suite[key] = nil
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Reset the given array of optional keys back to `nil`.
|
||||
|
@ -277,6 +216,19 @@ public final class Defaults {
|
|||
}
|
||||
}
|
||||
|
||||
extension Defaults.Key where Value: _DefaultsOptionalType {
|
||||
public convenience init(_ key: String, suite: UserDefaults = .standard) {
|
||||
self.init(key, default: nil, suite: suite)
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, iOSApplicationExtension 11.0, macOSApplicationExtension 10.13, tvOSApplicationExtension 11.0, watchOSApplicationExtension 4.0, *)
|
||||
extension Defaults.NSSecureCodingKey where Value: _DefaultsOptionalType {
|
||||
public convenience init(_ key: String, suite: UserDefaults = .standard) {
|
||||
self.init(key, default: nil, suite: suite)
|
||||
}
|
||||
}
|
||||
|
||||
extension UserDefaults {
|
||||
private func _get<Value: Codable>(_ key: String) -> Value? {
|
||||
if UserDefaults.isNativelySupportedType(Value.self) {
|
||||
|
@ -334,6 +286,11 @@ extension UserDefaults {
|
|||
}
|
||||
|
||||
private func _set<Value: Codable>(_ key: String, to value: Value) {
|
||||
if (value as? _DefaultsOptionalType)?.isNil == true {
|
||||
removeObject(forKey: key)
|
||||
return
|
||||
}
|
||||
|
||||
if UserDefaults.isNativelySupportedType(Value.self) {
|
||||
set(value, forKey: key)
|
||||
return
|
||||
|
@ -344,6 +301,7 @@ extension UserDefaults {
|
|||
|
||||
@available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, iOSApplicationExtension 11.0, macOSApplicationExtension 10.13, tvOSApplicationExtension 11.0, watchOSApplicationExtension 4.0, *)
|
||||
private func _set<Value: NSSecureCoding>(_ key: String, to value: Value) {
|
||||
// TODO: Handle nil here too.
|
||||
if UserDefaults.isNativelySupportedType(Value.self) {
|
||||
set(value, forKey: key)
|
||||
return
|
||||
|
@ -367,18 +325,6 @@ extension UserDefaults {
|
|||
}
|
||||
}
|
||||
|
||||
public subscript<Value: Codable>(key: Defaults.OptionalKey<Value>) -> Value? {
|
||||
get { _get(key.name) }
|
||||
set {
|
||||
guard let value = newValue else {
|
||||
set(nil, forKey: key.name)
|
||||
return
|
||||
}
|
||||
|
||||
_set(key.name, to: value)
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, iOSApplicationExtension 11.0, macOSApplicationExtension 10.13, tvOSApplicationExtension 11.0, watchOSApplicationExtension 4.0, *)
|
||||
public subscript<Value: NSSecureCoding>(key: Defaults.NSSecureCodingOptionalKey<Value>) -> Value? {
|
||||
get { _get(key.name) }
|
||||
|
@ -392,16 +338,23 @@ extension UserDefaults {
|
|||
}
|
||||
}
|
||||
|
||||
fileprivate static func isNativelySupportedType<Value>(_ type: Value.Type) -> Bool {
|
||||
fileprivate static func isNativelySupportedType<T>(_ type: T.Type) -> Bool {
|
||||
switch type {
|
||||
case
|
||||
is Bool.Type,
|
||||
is Bool?.Type, // swiftlint:disable:this discouraged_optional_boolean
|
||||
is String.Type,
|
||||
is String?.Type,
|
||||
is Int.Type,
|
||||
is Int?.Type,
|
||||
is Double.Type,
|
||||
is Double?.Type,
|
||||
is Float.Type,
|
||||
is Float?.Type,
|
||||
is Date.Type,
|
||||
is Data.Type:
|
||||
is Date?.Type,
|
||||
is Data.Type,
|
||||
is Data?.Type:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
|
|
@ -60,7 +60,7 @@ extension Defaults {
|
|||
self.options = options
|
||||
}
|
||||
|
||||
func receive<S>(subscriber: S) where S : Subscriber, DefaultsPublisher.Failure == S.Failure, DefaultsPublisher.Output == S.Input {
|
||||
func receive<S>(subscriber: S) where S: Subscriber, Failure == S.Failure, Output == S.Input {
|
||||
let subscription = DefaultsSubscription(
|
||||
subscriber: subscriber,
|
||||
suite: suite,
|
||||
|
@ -81,7 +81,7 @@ extension Defaults {
|
|||
static let isUnicornMode = Key<Bool>("isUnicornMode", default: false)
|
||||
}
|
||||
|
||||
let publisher = Defaults.publisher(.isUnicornMode).map { $0.newValue }
|
||||
let publisher = Defaults.publisher(.isUnicornMode).map(\.newValue)
|
||||
|
||||
let cancellable = publisher.sink { value in
|
||||
print(value)
|
||||
|
@ -114,20 +114,6 @@ extension Defaults {
|
|||
return AnyPublisher(publisher)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a type-erased `Publisher` that publishes changes related to the given optional key.
|
||||
*/
|
||||
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, iOSApplicationExtension 13.0, macOSApplicationExtension 10.15, tvOSApplicationExtension 13.0, watchOSApplicationExtension 6.0, *)
|
||||
public static func publisher<Value: Codable>(
|
||||
_ key: Defaults.OptionalKey<Value>,
|
||||
options: NSKeyValueObservingOptions = [.initial, .old, .new]
|
||||
) -> AnyPublisher<OptionalKeyChange<Value>, Never> {
|
||||
let publisher = DefaultsPublisher(suite: key.suite, key: key.name, options: options)
|
||||
.map { OptionalKeyChange<Value>(change: $0) }
|
||||
|
||||
return AnyPublisher(publisher)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a type-erased `Publisher` that publishes changes related to the given optional key.
|
||||
*/
|
||||
|
@ -154,29 +140,7 @@ extension Defaults {
|
|||
|
||||
let combinedPublisher =
|
||||
keys.map { key in
|
||||
return Defaults.publisher(key, options: options)
|
||||
.map { _ in () }
|
||||
.eraseToAnyPublisher()
|
||||
}.reduce(initial) { (combined, keyPublisher) in
|
||||
combined.merge(with: keyPublisher).eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
return combinedPublisher
|
||||
}
|
||||
|
||||
/**
|
||||
Publisher for multiple `OptionalKey<T>` observation, but without specific information about changes.
|
||||
*/
|
||||
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, iOSApplicationExtension 13.0, macOSApplicationExtension 10.15, tvOSApplicationExtension 13.0, watchOSApplicationExtension 6.0, *)
|
||||
public static func publisher<Value: Codable>(
|
||||
keys: Defaults.OptionalKey<Value>...,
|
||||
options: NSKeyValueObservingOptions = [.initial, .old, .new]
|
||||
) -> AnyPublisher<Void, Never> {
|
||||
let initial = Empty<Void, Never>(completeImmediately: false).eraseToAnyPublisher()
|
||||
|
||||
let combinedPublisher =
|
||||
keys.map { key in
|
||||
return Defaults.publisher(key, options: options)
|
||||
Defaults.publisher(key, options: options)
|
||||
.map { _ in () }
|
||||
.eraseToAnyPublisher()
|
||||
}.reduce(initial) { (combined, keyPublisher) in
|
||||
|
@ -198,7 +162,7 @@ extension Defaults {
|
|||
|
||||
let combinedPublisher =
|
||||
keys.map { key in
|
||||
return Defaults.publisher(key, options: options)
|
||||
Defaults.publisher(key, options: options)
|
||||
.map { _ in () }
|
||||
.eraseToAnyPublisher()
|
||||
}.reduce(initial) { (combined, keyPublisher) in
|
||||
|
@ -220,7 +184,7 @@ extension Defaults {
|
|||
|
||||
let combinedPublisher =
|
||||
keys.map { key in
|
||||
return Defaults.publisher(key, options: options)
|
||||
Defaults.publisher(key, options: options)
|
||||
.map { _ in () }
|
||||
.eraseToAnyPublisher()
|
||||
}.reduce(initial) { (combined, keyPublisher) in
|
||||
|
|
|
@ -113,22 +113,6 @@ extension Defaults {
|
|||
}
|
||||
}
|
||||
|
||||
public struct OptionalKeyChange<Value: Codable> {
|
||||
public let kind: NSKeyValueChange
|
||||
public let indexes: IndexSet?
|
||||
public let isPrior: Bool
|
||||
public let newValue: Value?
|
||||
public let oldValue: Value?
|
||||
|
||||
init(change: BaseChange) {
|
||||
self.kind = change.kind
|
||||
self.indexes = change.indexes
|
||||
self.isPrior = change.isPrior
|
||||
self.oldValue = deserialize(change.oldValue, to: Value.self)
|
||||
self.newValue = deserialize(change.newValue, to: Value.self)
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, iOSApplicationExtension 11.0, macOSApplicationExtension 10.13, tvOSApplicationExtension 11.0, watchOSApplicationExtension 4.0, *)
|
||||
public struct NSSecureCodingOptionalKeyChange<Value: NSSecureCoding> {
|
||||
public let kind: NSKeyValueChange
|
||||
|
@ -179,6 +163,7 @@ extension Defaults {
|
|||
lifetimeAssociation = LifetimeAssociation(of: self, with: weaklyHeldObject, deinitHandler: { [weak self] in
|
||||
self?.invalidate()
|
||||
})
|
||||
|
||||
return self
|
||||
}
|
||||
|
||||
|
@ -255,34 +240,6 @@ extension Defaults {
|
|||
return observation
|
||||
}
|
||||
|
||||
/**
|
||||
Observe an optional defaults key.
|
||||
|
||||
```
|
||||
extension Defaults.Keys {
|
||||
static let isUnicornMode = OptionalKey<Bool>("isUnicornMode")
|
||||
}
|
||||
|
||||
let observer = Defaults.observe(.isUnicornMode) { change in
|
||||
print(change.newValue)
|
||||
//=> Optional(nil)
|
||||
}
|
||||
```
|
||||
*/
|
||||
public static func observe<Value: Codable>(
|
||||
_ key: Defaults.OptionalKey<Value>,
|
||||
options: NSKeyValueObservingOptions = [.initial, .old, .new],
|
||||
handler: @escaping (OptionalKeyChange<Value>) -> Void
|
||||
) -> DefaultsObservation {
|
||||
let observation = UserDefaultsKeyObservation(object: key.suite, key: key.name) { change in
|
||||
handler(
|
||||
OptionalKeyChange<Value>(change: change)
|
||||
)
|
||||
}
|
||||
observation.start(options: options)
|
||||
return observation
|
||||
}
|
||||
|
||||
/**
|
||||
Observe an optional defaults key.
|
||||
*/
|
||||
|
|
|
@ -18,16 +18,19 @@ extension Decodable {
|
|||
}
|
||||
}
|
||||
|
||||
final class AssociatedObject<T: Any> {
|
||||
subscript(index: Any) -> T? {
|
||||
|
||||
final class ObjectAssociation<T: Any> {
|
||||
subscript(index: AnyObject) -> T? {
|
||||
get {
|
||||
return objc_getAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque()) as! T?
|
||||
} set {
|
||||
objc_getAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque()) as! T?
|
||||
}
|
||||
set {
|
||||
objc_setAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque(), newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Causes a given target object to live at least as long as a given owner object.
|
||||
*/
|
||||
|
@ -46,7 +49,7 @@ final class LifetimeAssociation {
|
|||
}
|
||||
}
|
||||
|
||||
private static let associatedObjects = AssociatedObject<[ObjectLifetimeTracker]>()
|
||||
private static let associatedObjects = ObjectAssociation<[ObjectLifetimeTracker]>()
|
||||
private weak var wrappedObject: ObjectLifetimeTracker?
|
||||
private weak var owner: AnyObject?
|
||||
|
||||
|
@ -113,3 +116,19 @@ final class LifetimeAssociation {
|
|||
self.owner = nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// A protocol for making generic type constraints of optionals.
|
||||
/// - Note: It's intentionally not including `associatedtype Wrapped` as that limits a lot of the use-cases.
|
||||
public protocol _DefaultsOptionalType: ExpressibleByNilLiteral {
|
||||
/// This is useful as you can't compare `_OptionalType` to `nil`.
|
||||
var isNil: Bool { get }
|
||||
}
|
||||
|
||||
extension Optional: _DefaultsOptionalType {
|
||||
public var isNil: Bool { self == nil }
|
||||
}
|
||||
|
||||
func isOptionalType<T>(_ type: T.Type) -> Bool {
|
||||
type is _DefaultsOptionalType.Type
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import Foundation
|
||||
import XCTest
|
||||
import Defaults
|
||||
import CoreData
|
||||
import Combine
|
||||
import XCTest
|
||||
import Defaults
|
||||
|
||||
let fixtureURL = URL(string: "https://sindresorhus.com")!
|
||||
let fixtureURL2 = URL(string: "https://example.com")!
|
||||
|
@ -17,7 +17,6 @@ let fixtureDate = Date()
|
|||
|
||||
@available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, iOSApplicationExtension 11.0, macOSApplicationExtension 10.13, tvOSApplicationExtension 11.0, watchOSApplicationExtension 4.0, *)
|
||||
final class ExamplePersistentHistory: NSPersistentHistoryToken {
|
||||
|
||||
let value: String
|
||||
|
||||
init(value: String) {
|
||||
|
@ -34,9 +33,7 @@ final class ExamplePersistentHistory: NSPersistentHistoryToken {
|
|||
coder.encode(value, forKey: "value")
|
||||
}
|
||||
|
||||
override class var supportsSecureCoding: Bool {
|
||||
return true
|
||||
}
|
||||
override class var supportsSecureCoding: Bool { true }
|
||||
}
|
||||
|
||||
extension Defaults.Keys {
|
||||
|
@ -72,7 +69,7 @@ final class DefaultsTests: XCTestCase {
|
|||
}
|
||||
|
||||
func testOptionalKey() {
|
||||
let key = Defaults.OptionalKey<Bool>("independentOptionalKey")
|
||||
let key = Defaults.Key<Bool?>("independentOptionalKey")
|
||||
XCTAssertNil(Defaults[key])
|
||||
Defaults[key] = true
|
||||
XCTAssertTrue(Defaults[key]!)
|
||||
|
@ -227,7 +224,7 @@ final class DefaultsTests: XCTestCase {
|
|||
|
||||
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, iOSApplicationExtension 13.0, macOSApplicationExtension 10.15, tvOSApplicationExtension 13.0, watchOSApplicationExtension 6.0, *)
|
||||
func testObserveOptionalKeyCombine() {
|
||||
let key = Defaults.OptionalKey<Bool>("observeOptionalKey")
|
||||
let key = Defaults.Key<Bool?>("observeOptionalKey")
|
||||
let expect = expectation(description: "Observation closure being called")
|
||||
|
||||
let publisher = Defaults
|
||||
|
@ -348,8 +345,8 @@ final class DefaultsTests: XCTestCase {
|
|||
|
||||
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, iOSApplicationExtension 13.0, macOSApplicationExtension 10.15, tvOSApplicationExtension 13.0, watchOSApplicationExtension 6.0, *)
|
||||
func testObserveMultipleOptionalKeysCombine() {
|
||||
let key1 = Defaults.OptionalKey<Bool>("observeOptionalKey1")
|
||||
let key2 = Defaults.OptionalKey<Bool>("observeOptionalKey2")
|
||||
let key1 = Defaults.Key<Bool?>("observeOptionalKey1")
|
||||
let key2 = Defaults.Key<Bool?>("observeOptionalKey2")
|
||||
let expect = expectation(description: "Observation closure being called")
|
||||
|
||||
let publisher = Defaults.publisher(keys: key1, key2, options: [.old, .new]).collect(2)
|
||||
|
@ -441,7 +438,7 @@ final class DefaultsTests: XCTestCase {
|
|||
}
|
||||
|
||||
func testObserveOptionalKey() {
|
||||
let key = Defaults.OptionalKey<Bool>("observeOptionalKey")
|
||||
let key = Defaults.Key<Bool?>("observeOptionalKey")
|
||||
let expect = expectation(description: "Observation closure being called")
|
||||
|
||||
var observation: DefaultsObservation!
|
||||
|
@ -558,8 +555,8 @@ final class DefaultsTests: XCTestCase {
|
|||
let newString1 = "bar1"
|
||||
let newString2 = "bar2"
|
||||
let newString3 = "bar3"
|
||||
let key1 = Defaults.OptionalKey<String>("optionalKey1")
|
||||
let key2 = Defaults.OptionalKey<String>("optionalKey2")
|
||||
let key1 = Defaults.Key<String?>("optionalKey1")
|
||||
let key2 = Defaults.Key<String?>("optionalKey2")
|
||||
Defaults[key1] = newString1
|
||||
Defaults[key2] = newString2
|
||||
Defaults.reset(key1)
|
||||
|
@ -578,9 +575,9 @@ final class DefaultsTests: XCTestCase {
|
|||
let newString1 = "bar1"
|
||||
let newString2 = "bar2"
|
||||
let newString3 = "bar3"
|
||||
let key1 = Defaults.OptionalKey<String>("aoptionalKey1")
|
||||
let key2 = Defaults.OptionalKey<String>("aoptionalKey2")
|
||||
let key3 = Defaults.OptionalKey<String>("aoptionalKey3")
|
||||
let key1 = Defaults.Key<String?>("aoptionalKey1")
|
||||
let key2 = Defaults.Key<String?>("aoptionalKey2")
|
||||
let key3 = Defaults.Key<String?>("aoptionalKey3")
|
||||
Defaults[key1] = newString1
|
||||
Defaults[key2] = newString2
|
||||
Defaults[key3] = newString3
|
||||
|
|
40
readme.md
40
readme.md
|
@ -2,7 +2,7 @@
|
|||
|
||||
> Swifty and modern [UserDefaults](https://developer.apple.com/documentation/foundation/userdefaults)
|
||||
|
||||
**Note:** The readme reflects the master branch. [Click here](https://github.com/sindresorhus/Defaults/tree/55ffea9487fb9b559406d909ee31dcd955fe77aa#readme) for docs for the latest version. The code in the master branch cannot be released until Apple fixes [this bug](https://github.com/feedback-assistant/reports/issues/44).
|
||||
#### Note: The readme reflects the master branch. [Click here](https://github.com/sindresorhus/Defaults/tree/55ffea9487fb9b559406d909ee31dcd955fe77aa#readme) for docs for the latest version. The code in the master branch cannot be released until Apple fixes [this bug](https://github.com/feedback-assistant/reports/issues/44).
|
||||
|
||||
It uses `NSUserDefaults` underneath but exposes a type-safe facade with lots of nice conveniences.
|
||||
|
||||
|
@ -80,7 +80,7 @@ You can also declare optional keys for when you don't want to declare a default
|
|||
|
||||
```swift
|
||||
extension Defaults.Keys {
|
||||
static let name = OptionalKey<Double>("name")
|
||||
static let name = Key<Double?>("name")
|
||||
}
|
||||
|
||||
if let name = Defaults[.name] {
|
||||
|
@ -228,7 +228,7 @@ Defaults[.isUnicornMode]
|
|||
//=> false
|
||||
```
|
||||
|
||||
This works for `OptionalKey` too, which will be reset back to `nil`.
|
||||
This works for a `Key` with an optional too, which will be reset back to `nil`.
|
||||
|
||||
### It's just `UserDefaults` with sugar
|
||||
|
||||
|
@ -308,16 +308,6 @@ Create a NSSecureCoding key with a default value.
|
|||
|
||||
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`)*
|
||||
|
||||
```swift
|
||||
Defaults.OptionalKey<T>(_ key: String, suite: UserDefaults = .standard)
|
||||
```
|
||||
|
||||
Type: `class`
|
||||
|
||||
Create a key with an optional value.
|
||||
|
||||
#### `Defaults.NSSecureCodingOptionalKey` *(alias `Defaults.Keys.NSSecureCodingOptionalKey`)*
|
||||
|
||||
```swift
|
||||
|
@ -333,8 +323,6 @@ Create a NSSecureCoding key with an optional value.
|
|||
```swift
|
||||
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)
|
||||
|
||||
Defaults.reset<T: Codable>(_ keys: Defaults.NSSecureCodingKey<T>..., suite: UserDefaults = .standard)
|
||||
Defaults.reset<T: Codable>(_ keys: [Defaults.NSSecureCodingKey<T>], suite: UserDefaults = .standard)
|
||||
|
@ -364,14 +352,6 @@ Defaults.observe<T: NSSecureCoding>(
|
|||
) -> DefaultsObservation
|
||||
```
|
||||
|
||||
```swift
|
||||
Defaults.observe<T: Codable>(
|
||||
_ key: Defaults.OptionalKey<T>,
|
||||
options: NSKeyValueObservingOptions = [.initial, .old, .new],
|
||||
handler: @escaping (OptionalKeyChange<T>) -> Void
|
||||
) -> DefaultsObservation
|
||||
```
|
||||
|
||||
```swift
|
||||
Defaults.observe<T: NSSecureCoding>(
|
||||
_ key: Defaults.NSSecureCodingOptionalKey<T>,
|
||||
|
@ -402,13 +382,6 @@ Defaults.publisher<T: NSSecureCoding>(
|
|||
) -> AnyPublisher<NSSecureCodingKeyChange<T>, Never>
|
||||
```
|
||||
|
||||
```swift
|
||||
Defaults.publisher<T: Codable>(
|
||||
_ key: Defaults.OptionalKey<T>,
|
||||
options: NSKeyValueObservingOptions = [.initial, .old, .new]
|
||||
) -> AnyPublisher<OptionalKeyChange<T>, Never>
|
||||
```
|
||||
|
||||
```swift
|
||||
Defaults.publisher<T: NSSecureCoding>(
|
||||
_ key: Defaults.NSSecureCodingOptionalKey<T>,
|
||||
|
@ -438,13 +411,6 @@ Defaults.publisher<T: NSSecureCoding>(
|
|||
) -> AnyPublisher<Void, Never> {
|
||||
```
|
||||
|
||||
```swift
|
||||
Defaults.publisher<T: Codable>(
|
||||
keys: Defaults.OptionalKey<T>...,
|
||||
options: NSKeyValueObservingOptions = [.initial, .old, .new]
|
||||
) -> AnyPublisher<Void, Never> {
|
||||
```
|
||||
|
||||
```swift
|
||||
Defaults.publisher<T: NSSecureCoding>(
|
||||
keys: Defaults.NSSecureCodingOptionalKey<T>...,
|
||||
|
|
Loading…
Reference in New Issue