Remove the `.old` and `.new` options

They are now `true` by default.

Fixes #33
This commit is contained in:
Sindre Sorhus 2020-04-13 13:14:55 +08:00
parent c34559cc58
commit 8376ca7f51
4 changed files with 74 additions and 50 deletions

View File

@ -11,9 +11,9 @@ extension Defaults {
final class DefaultsSubscription<SubscriberType: Subscriber>: Subscription where SubscriberType.Input == BaseChange { final class DefaultsSubscription<SubscriberType: Subscriber>: Subscription where SubscriberType.Input == BaseChange {
private var subscriber: SubscriberType? private var subscriber: SubscriberType?
private var observation: UserDefaultsKeyObservation? private var observation: UserDefaultsKeyObservation?
private let options: NSKeyValueObservingOptions private let options: ObservationOptions
init(subscriber: SubscriberType, suite: UserDefaults, key: String, options: NSKeyValueObservingOptions) { init(subscriber: SubscriberType, suite: UserDefaults, key: String, options: ObservationOptions) {
self.subscriber = subscriber self.subscriber = subscriber
self.options = options self.options = options
self.observation = UserDefaultsKeyObservation( self.observation = UserDefaultsKeyObservation(
@ -52,9 +52,9 @@ extension Defaults {
private let suite: UserDefaults private let suite: UserDefaults
private let key: String private let key: String
private let options: NSKeyValueObservingOptions private let options: ObservationOptions
init(suite: UserDefaults, key: String, options: NSKeyValueObservingOptions) { init(suite: UserDefaults, key: String, options: ObservationOptions) {
self.suite = suite self.suite = suite
self.key = key self.key = key
self.options = options self.options = options
@ -91,8 +91,8 @@ extension Defaults {
*/ */
@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, *) @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>( public static func publisher<Value: Codable>(
_ key: Defaults.Key<Value>, _ key: Key<Value>,
options: NSKeyValueObservingOptions = [.initial, .old, .new] options: ObservationOptions = [.initial]
) -> AnyPublisher<KeyChange<Value>, Never> { ) -> AnyPublisher<KeyChange<Value>, Never> {
let publisher = DefaultsPublisher(suite: key.suite, key: key.name, options: options) let publisher = DefaultsPublisher(suite: key.suite, key: key.name, options: options)
.map { KeyChange<Value>(change: $0, defaultValue: key.defaultValue) } .map { KeyChange<Value>(change: $0, defaultValue: key.defaultValue) }
@ -105,8 +105,8 @@ extension Defaults {
*/ */
@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, *) @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: NSSecureCoding>( public static func publisher<Value: NSSecureCoding>(
_ key: Defaults.NSSecureCodingKey<Value>, _ key: NSSecureCodingKey<Value>,
options: NSKeyValueObservingOptions = [.initial, .old, .new] options: ObservationOptions = [.initial]
) -> AnyPublisher<NSSecureCodingKeyChange<Value>, Never> { ) -> AnyPublisher<NSSecureCodingKeyChange<Value>, Never> {
let publisher = DefaultsPublisher(suite: key.suite, key: key.name, options: options) let publisher = DefaultsPublisher(suite: key.suite, key: key.name, options: options)
.map { NSSecureCodingKeyChange<Value>(change: $0, defaultValue: key.defaultValue) } .map { NSSecureCodingKeyChange<Value>(change: $0, defaultValue: key.defaultValue) }
@ -119,8 +119,8 @@ extension Defaults {
*/ */
@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, *) @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: NSSecureCoding>( public static func publisher<Value: NSSecureCoding>(
_ key: Defaults.NSSecureCodingOptionalKey<Value>, _ key: NSSecureCodingOptionalKey<Value>,
options: NSKeyValueObservingOptions = [.initial, .old, .new] options: ObservationOptions = [.initial]
) -> AnyPublisher<NSSecureCodingOptionalKeyChange<Value>, Never> { ) -> AnyPublisher<NSSecureCodingOptionalKeyChange<Value>, Never> {
let publisher = DefaultsPublisher(suite: key.suite, key: key.name, options: options) let publisher = DefaultsPublisher(suite: key.suite, key: key.name, options: options)
.map { NSSecureCodingOptionalKeyChange<Value>(change: $0) } .map { NSSecureCodingOptionalKeyChange<Value>(change: $0) }
@ -133,8 +133,8 @@ extension Defaults {
*/ */
@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, *) @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>( public static func publisher<Value: Codable>(
keys: Defaults.Key<Value>..., keys:Key<Value>...,
options: NSKeyValueObservingOptions = [.initial, .old, .new] options: ObservationOptions = [.initial]
) -> AnyPublisher<Void, Never> { ) -> AnyPublisher<Void, Never> {
let initial = Empty<Void, Never>(completeImmediately: false).eraseToAnyPublisher() let initial = Empty<Void, Never>(completeImmediately: false).eraseToAnyPublisher()
@ -156,7 +156,7 @@ extension Defaults {
@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, *) @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: NSSecureCoding>( public static func publisher<Value: NSSecureCoding>(
keys: Defaults.NSSecureCodingKey<Value>..., keys: Defaults.NSSecureCodingKey<Value>...,
options: NSKeyValueObservingOptions = [.initial, .old, .new] options: ObservationOptions = [.initial]
) -> AnyPublisher<Void, Never> { ) -> AnyPublisher<Void, Never> {
let initial = Empty<Void, Never>(completeImmediately: false).eraseToAnyPublisher() let initial = Empty<Void, Never>(completeImmediately: false).eraseToAnyPublisher()
@ -178,7 +178,7 @@ extension Defaults {
@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, *) @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: NSSecureCoding>( public static func publisher<Value: NSSecureCoding>(
keys: Defaults.NSSecureCodingOptionalKey<Value>..., keys: Defaults.NSSecureCodingOptionalKey<Value>...,
options: NSKeyValueObservingOptions = [.initial, .old, .new] options: ObservationOptions = [.initial]
) -> AnyPublisher<Void, Never> { ) -> AnyPublisher<Void, Never> {
let initial = Empty<Void, Never>(completeImmediately: false).eraseToAnyPublisher() let initial = Empty<Void, Never>(completeImmediately: false).eraseToAnyPublisher()

View File

@ -27,6 +27,16 @@ public protocol DefaultsObservation: AnyObject {
extension Defaults { extension Defaults {
public typealias Observation = DefaultsObservation public typealias Observation = DefaultsObservation
public enum ObservationOption {
/// Whether a notification should be sent to the observer immediately, before the observer registration method even returns.
case initial
/// Whether separate notifications should be sent to the observer before and after each change, instead of a single notification after the change.
case prior
}
public typealias ObservationOptions = Set<ObservationOption>
private static func deserialize<Value: Decodable>(_ value: Any?, to type: Value.Type) -> Value? { private static func deserialize<Value: Decodable>(_ value: Any?, to type: Value.Type) -> Value? {
guard guard
let value = value, let value = value,
@ -131,7 +141,7 @@ extension Defaults {
} }
} }
final class UserDefaultsKeyObservation: NSObject, Defaults.Observation { final class UserDefaultsKeyObservation: NSObject, Observation {
typealias Callback = (BaseChange) -> Void typealias Callback = (BaseChange) -> Void
private weak var object: UserDefaults? private weak var object: UserDefaults?
@ -148,8 +158,8 @@ extension Defaults {
invalidate() invalidate()
} }
func start(options: NSKeyValueObservingOptions) { func start(options: ObservationOptions) {
object?.addObserver(self, forKeyPath: key, options: options, context: nil) object?.addObserver(self, forKeyPath: key, options: options.toNSKeyValueObservingOptions, context: nil)
} }
public func invalidate() { public func invalidate() {
@ -210,10 +220,10 @@ extension Defaults {
``` ```
*/ */
public static func observe<Value: Codable>( public static func observe<Value: Codable>(
_ key: Defaults.Key<Value>, _ key: Key<Value>,
options: NSKeyValueObservingOptions = [.initial, .old, .new], options: ObservationOptions = [.initial],
handler: @escaping (KeyChange<Value>) -> Void handler: @escaping (KeyChange<Value>) -> Void
) -> Defaults.Observation { ) -> Observation {
let observation = UserDefaultsKeyObservation(object: key.suite, key: key.name) { change in let observation = UserDefaultsKeyObservation(object: key.suite, key: key.name) { change in
handler( handler(
KeyChange<Value>(change: change, defaultValue: key.defaultValue) KeyChange<Value>(change: change, defaultValue: key.defaultValue)
@ -228,10 +238,10 @@ extension 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, *) @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 func observe<Value: NSSecureCoding>( public static func observe<Value: NSSecureCoding>(
_ key: Defaults.NSSecureCodingKey<Value>, _ key: NSSecureCodingKey<Value>,
options: NSKeyValueObservingOptions = [.initial, .old, .new], options: ObservationOptions = [.initial],
handler: @escaping (NSSecureCodingKeyChange<Value>) -> Void handler: @escaping (NSSecureCodingKeyChange<Value>) -> Void
) -> Defaults.Observation { ) -> Observation {
let observation = UserDefaultsKeyObservation(object: key.suite, key: key.name) { change in let observation = UserDefaultsKeyObservation(object: key.suite, key: key.name) { change in
handler( handler(
NSSecureCodingKeyChange<Value>(change: change, defaultValue: key.defaultValue) NSSecureCodingKeyChange<Value>(change: change, defaultValue: key.defaultValue)
@ -246,10 +256,10 @@ extension 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, *) @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 func observe<Value: NSSecureCoding>( public static func observe<Value: NSSecureCoding>(
_ key: Defaults.NSSecureCodingOptionalKey<Value>, _ key: NSSecureCodingOptionalKey<Value>,
options: NSKeyValueObservingOptions = [.initial, .old, .new], options: ObservationOptions = [.initial],
handler: @escaping (NSSecureCodingOptionalKeyChange<Value>) -> Void handler: @escaping (NSSecureCodingOptionalKeyChange<Value>) -> Void
) -> Defaults.Observation { ) -> Observation {
let observation = UserDefaultsKeyObservation(object: key.suite, key: key.name) { change in let observation = UserDefaultsKeyObservation(object: key.suite, key: key.name) { change in
handler( handler(
NSSecureCodingOptionalKeyChange<Value>(change: change) NSSecureCodingOptionalKeyChange<Value>(change: change)
@ -259,3 +269,17 @@ extension Defaults {
return observation return observation
} }
} }
extension Defaults.ObservationOptions {
var toNSKeyValueObservingOptions: NSKeyValueObservingOptions {
var options: NSKeyValueObservingOptions = [.old, .new]
if contains(.initial) {
options.insert(.initial)
} else if contains(.prior) {
options.insert(.prior)
}
return options
}
}

View File

@ -169,7 +169,7 @@ final class DefaultsTests: XCTestCase {
let expect = expectation(description: "Observation closure being called") let expect = expectation(description: "Observation closure being called")
let publisher = Defaults let publisher = Defaults
.publisher(key, options: [.old, .new]) .publisher(key, options: [])
.map { ($0.oldValue, $0.newValue) } .map { ($0.oldValue, $0.newValue) }
.collect(2) .collect(2)
@ -195,7 +195,7 @@ final class DefaultsTests: XCTestCase {
let expect = expectation(description: "Observation closure being called") let expect = expectation(description: "Observation closure being called")
let publisher = Defaults let publisher = Defaults
.publisher(key, options: [.old, .new]) .publisher(key, options: [])
.map { ($0.oldValue.value, $0.newValue.value) } .map { ($0.oldValue.value, $0.newValue.value) }
.collect(3) .collect(3)
@ -228,7 +228,7 @@ final class DefaultsTests: XCTestCase {
let expect = expectation(description: "Observation closure being called") let expect = expectation(description: "Observation closure being called")
let publisher = Defaults let publisher = Defaults
.publisher(key, options: [.old, .new]) .publisher(key, options: [])
.map { ($0.oldValue, $0.newValue) } .map { ($0.oldValue, $0.newValue) }
.collect(3) .collect(3)
@ -257,7 +257,7 @@ final class DefaultsTests: XCTestCase {
let expect = expectation(description: "Observation closure being called") let expect = expectation(description: "Observation closure being called")
let publisher = Defaults let publisher = Defaults
.publisher(key, options: [.old, .new]) .publisher(key, options: [])
.map { ($0.oldValue?.value, $0.newValue?.value) } .map { ($0.oldValue?.value, $0.newValue?.value) }
.collect(3) .collect(3)
@ -309,7 +309,7 @@ final class DefaultsTests: XCTestCase {
let key2 = Defaults.Key<Bool>("observeKey2", default: true) let key2 = Defaults.Key<Bool>("observeKey2", default: true)
let expect = expectation(description: "Observation closure being called") let expect = expectation(description: "Observation closure being called")
let publisher = Defaults.publisher(keys: key1, key2, options: [.old, .new]).collect(2) let publisher = Defaults.publisher(keys: key1, key2, options: []).collect(2)
let cancellable = publisher.sink { _ in let cancellable = publisher.sink { _ in
expect.fulfill() expect.fulfill()
@ -329,7 +329,7 @@ final class DefaultsTests: XCTestCase {
let key2 = Defaults.NSSecureCodingKey<ExamplePersistentHistory>("observeNSSecureCodingKey2", default: ExamplePersistentHistory(value: "TestValue")) let key2 = Defaults.NSSecureCodingKey<ExamplePersistentHistory>("observeNSSecureCodingKey2", default: ExamplePersistentHistory(value: "TestValue"))
let expect = expectation(description: "Observation closure being called") let expect = expectation(description: "Observation closure being called")
let publisher = Defaults.publisher(keys: key1, key2, options: [.old, .new]).collect(2) let publisher = Defaults.publisher(keys: key1, key2, options: []).collect(2)
let cancellable = publisher.sink { _ in let cancellable = publisher.sink { _ in
expect.fulfill() expect.fulfill()
@ -349,7 +349,7 @@ final class DefaultsTests: XCTestCase {
let key2 = Defaults.Key<Bool?>("observeOptionalKey2") let key2 = Defaults.Key<Bool?>("observeOptionalKey2")
let expect = expectation(description: "Observation closure being called") let expect = expectation(description: "Observation closure being called")
let publisher = Defaults.publisher(keys: key1, key2, options: [.old, .new]).collect(2) let publisher = Defaults.publisher(keys: key1, key2, options: []).collect(2)
let cancellable = publisher.sink { _ in let cancellable = publisher.sink { _ in
expect.fulfill() expect.fulfill()
@ -368,7 +368,7 @@ final class DefaultsTests: XCTestCase {
let key2 = Defaults.NSSecureCodingOptionalKey<ExamplePersistentHistory>("observeNSSecureCodingKey2") let key2 = Defaults.NSSecureCodingOptionalKey<ExamplePersistentHistory>("observeNSSecureCodingKey2")
let expect = expectation(description: "Observation closure being called") let expect = expectation(description: "Observation closure being called")
let publisher = Defaults.publisher(keys: key1, key2, options: [.old, .new]).collect(2) let publisher = Defaults.publisher(keys: key1, key2, options: []).collect(2)
let cancellable = publisher.sink { _ in let cancellable = publisher.sink { _ in
expect.fulfill() expect.fulfill()
@ -387,7 +387,7 @@ final class DefaultsTests: XCTestCase {
let expect = expectation(description: "Observation closure being called") let expect = expectation(description: "Observation closure being called")
let publisher = Defaults let publisher = Defaults
.publisher(key, options: [.initial, .new]) .publisher(key)
.compactMap { $0.newValue } .compactMap { $0.newValue }
.eraseToAnyPublisher() .eraseToAnyPublisher()
.collect(2) .collect(2)
@ -407,7 +407,7 @@ final class DefaultsTests: XCTestCase {
let expect = expectation(description: "Observation closure being called") let expect = expectation(description: "Observation closure being called")
var observation: Defaults.Observation! var observation: Defaults.Observation!
observation = Defaults.observe(key, options: [.old, .new]) { change in observation = Defaults.observe(key, options: []) { change in
XCTAssertFalse(change.oldValue) XCTAssertFalse(change.oldValue)
XCTAssertTrue(change.newValue) XCTAssertTrue(change.newValue)
observation.invalidate() observation.invalidate()
@ -425,7 +425,7 @@ final class DefaultsTests: XCTestCase {
let expect = expectation(description: "Observation closure being called") let expect = expectation(description: "Observation closure being called")
var observation: Defaults.Observation! var observation: Defaults.Observation!
observation = Defaults.observe(key, options: [.old, .new]) { change in observation = Defaults.observe(key, options: []) { change in
XCTAssertEqual(change.oldValue.value, "TestValue") XCTAssertEqual(change.oldValue.value, "TestValue")
XCTAssertEqual(change.newValue.value, "NewTestValue") XCTAssertEqual(change.newValue.value, "NewTestValue")
observation.invalidate() observation.invalidate()
@ -442,7 +442,7 @@ final class DefaultsTests: XCTestCase {
let expect = expectation(description: "Observation closure being called") let expect = expectation(description: "Observation closure being called")
var observation: Defaults.Observation! var observation: Defaults.Observation!
observation = Defaults.observe(key, options: [.old, .new]) { change in observation = Defaults.observe(key, options: []) { change in
XCTAssertNil(change.oldValue) XCTAssertNil(change.oldValue)
XCTAssertTrue(change.newValue!) XCTAssertTrue(change.newValue!)
observation.invalidate() observation.invalidate()
@ -460,7 +460,7 @@ final class DefaultsTests: XCTestCase {
let expect = expectation(description: "Observation closure being called") let expect = expectation(description: "Observation closure being called")
var observation: Defaults.Observation! var observation: Defaults.Observation!
observation = Defaults.observe(key, options: [.old, .new]) { change in observation = Defaults.observe(key, options: []) { change in
XCTAssertNil(change.oldValue) XCTAssertNil(change.oldValue)
XCTAssertEqual(change.newValue?.value, "NewOptionalValue") XCTAssertEqual(change.newValue?.value, "NewOptionalValue")
observation.invalidate() observation.invalidate()
@ -479,7 +479,7 @@ final class DefaultsTests: XCTestCase {
let expect = expectation(description: "Observation closure being called") let expect = expectation(description: "Observation closure being called")
var observation: Defaults.Observation! var observation: Defaults.Observation!
observation = Defaults.observe(key, options: [.old, .new]) { change in observation = Defaults.observe(key, options: []) { change in
XCTAssertEqual(change.oldValue, fixtureURL) XCTAssertEqual(change.oldValue, fixtureURL)
XCTAssertEqual(change.newValue, fixtureURL2) XCTAssertEqual(change.newValue, fixtureURL2)
observation.invalidate() observation.invalidate()
@ -496,7 +496,7 @@ final class DefaultsTests: XCTestCase {
let expect = expectation(description: "Observation closure being called") let expect = expectation(description: "Observation closure being called")
var observation: Defaults.Observation! var observation: Defaults.Observation!
observation = Defaults.observe(key, options: [.old, .new]) { change in observation = Defaults.observe(key, options: []) { change in
XCTAssertEqual(change.oldValue, .oneHour) XCTAssertEqual(change.oldValue, .oneHour)
XCTAssertEqual(change.newValue, .tenMinutes) XCTAssertEqual(change.newValue, .tenMinutes)
observation.invalidate() observation.invalidate()

View File

@ -339,7 +339,7 @@ Reset the given keys back to their default values.
```swift ```swift
Defaults.observe<T: Codable>( Defaults.observe<T: Codable>(
_ key: Defaults.Key<T>, _ key: Defaults.Key<T>,
options: NSKeyValueObservingOptions = [.initial, .old, .new], options: ObservationOptions = [.initial],
handler: @escaping (KeyChange<T>) -> Void handler: @escaping (KeyChange<T>) -> Void
) -> Defaults.Observation ) -> Defaults.Observation
``` ```
@ -347,7 +347,7 @@ Defaults.observe<T: Codable>(
```swift ```swift
Defaults.observe<T: NSSecureCoding>( Defaults.observe<T: NSSecureCoding>(
_ key: Defaults.NSSecureCodingKey<T>, _ key: Defaults.NSSecureCodingKey<T>,
options: NSKeyValueObservingOptions = [.initial, .old, .new], options: ObservationOptions = [.initial],
handler: @escaping (NSSecureCodingKeyChange<T>) -> Void handler: @escaping (NSSecureCodingKeyChange<T>) -> Void
) -> Defaults.Observation ) -> Defaults.Observation
``` ```
@ -355,7 +355,7 @@ Defaults.observe<T: NSSecureCoding>(
```swift ```swift
Defaults.observe<T: NSSecureCoding>( Defaults.observe<T: NSSecureCoding>(
_ key: Defaults.NSSecureCodingOptionalKey<T>, _ key: Defaults.NSSecureCodingOptionalKey<T>,
options: NSKeyValueObservingOptions = [.initial, .old, .new], options: ObservationOptions = [.initial],
handler: @escaping (NSSecureCodingOptionalKeyChange<T>) -> Void handler: @escaping (NSSecureCodingOptionalKeyChange<T>) -> Void
) -> Defaults.Observation ) -> Defaults.Observation
``` ```
@ -371,21 +371,21 @@ By default, it will also trigger an initial event on creation. This can be usefu
```swift ```swift
Defaults.publisher<T: Codable>( Defaults.publisher<T: Codable>(
_ key: Defaults.Key<T>, _ key: Defaults.Key<T>,
options: NSKeyValueObservingOptions = [.initial, .old, .new] options: ObservationOptions = [.initial]
) -> AnyPublisher<KeyChange<T>, Never> ) -> AnyPublisher<KeyChange<T>, Never>
``` ```
```swift ```swift
Defaults.publisher<T: NSSecureCoding>( Defaults.publisher<T: NSSecureCoding>(
_ key: Defaults.NSSecureCodingKey<T>, _ key: Defaults.NSSecureCodingKey<T>,
options: NSKeyValueObservingOptions = [.initial, .old, .new] options: ObservationOptions = [.initial]
) -> AnyPublisher<NSSecureCodingKeyChange<T>, Never> ) -> AnyPublisher<NSSecureCodingKeyChange<T>, Never>
``` ```
```swift ```swift
Defaults.publisher<T: NSSecureCoding>( Defaults.publisher<T: NSSecureCoding>(
_ key: Defaults.NSSecureCodingOptionalKey<T>, _ key: Defaults.NSSecureCodingOptionalKey<T>,
options: NSKeyValueObservingOptions = [.initial, .old, .new] options: ObservationOptions = [.initial]
) -> AnyPublisher<NSSecureCodingOptionalKeyChange<T>, Never> ) -> AnyPublisher<NSSecureCodingOptionalKeyChange<T>, Never>
``` ```
@ -400,21 +400,21 @@ Available on macOS 10.15+, iOS 13.0+, tvOS 13.0+, and watchOS 6.0+.
```swift ```swift
Defaults.publisher<T: Codable>( Defaults.publisher<T: Codable>(
keys: Defaults.Key<T>..., keys: Defaults.Key<T>...,
options: NSKeyValueObservingOptions = [.initial, .old, .new] options: ObservationOptions = [.initial]
) -> AnyPublisher<Void, Never> { ) -> AnyPublisher<Void, Never> {
``` ```
```swift ```swift
Defaults.publisher<T: NSSecureCoding>( Defaults.publisher<T: NSSecureCoding>(
keys: Defaults.NSSecureCodingKey<T>..., keys: Defaults.NSSecureCodingKey<T>...,
options: NSKeyValueObservingOptions = [.initial, .old, .new] options: ObservationOptions = [.initial]
) -> AnyPublisher<Void, Never> { ) -> AnyPublisher<Void, Never> {
``` ```
```swift ```swift
Defaults.publisher<T: NSSecureCoding>( Defaults.publisher<T: NSSecureCoding>(
keys: Defaults.NSSecureCodingOptionalKey<T>..., keys: Defaults.NSSecureCodingOptionalKey<T>...,
options: NSKeyValueObservingOptions = [.initial, .old, .new] options: ObservationOptions = [.initial]
) -> AnyPublisher<Void, Never> { ) -> AnyPublisher<Void, Never> {
``` ```