Skip to content

Commit

Permalink
Fix crash in the Combine API (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
fredyshox committed Apr 5, 2020
1 parent ca813bf commit 3275717
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
8 changes: 7 additions & 1 deletion Sources/Defaults/Observation+Combine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ extension Defaults {
final class DefaultsSubscription<SubscriberType: Subscriber>: Subscription where SubscriberType.Input == BaseChange {
private var subscriber: SubscriberType?
private var observation: UserDefaultsKeyObservation?
private let options: NSKeyValueObservingOptions

init(subscriber: SubscriberType, suite: UserDefaults, key: String, options: NSKeyValueObservingOptions) {
self.subscriber = subscriber
self.options = options
self.observation = UserDefaultsKeyObservation(
object: suite,
key: key,
callback: observationCallback(_:)
)
self.observation?.start(options: options)
}

func request(_ demand: Subscribers.Demand) {
Expand All @@ -32,6 +33,10 @@ extension Defaults {
subscriber = nil
}

func start() {
observation?.start(options: options)
}

private func observationCallback(_ change: BaseChange) {
_ = subscriber?.receive(change)
}
Expand Down Expand Up @@ -64,6 +69,7 @@ extension Defaults {
)

subscriber.receive(subscription: subscription)
subscription.start()
}
}

Expand Down
21 changes: 21 additions & 0 deletions Tests/DefaultsTests/DefaultsTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,27 @@ final class DefaultsTests: XCTestCase {
waitForExpectations(timeout: 10)
}

@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 testReceiveValueBeforeSubscriptionCombine() {
let key = Defaults.Key<String>("receiveValueBeforeSubscription", default: "hello")
let expect = expectation(description: "Observation closure being called")

let publisher = Defaults
.publisher(key, options: [.initial, .new])
.compactMap { $0.newValue }
.eraseToAnyPublisher()
.collect(2)

let cancellable = publisher.sink { values in
XCTAssertEqual(["hello", "world"], values)
expect.fulfill()
}

Defaults[key] = "world";
cancellable.cancel()
waitForExpectations(timeout: 10)
}

func testObserveKey() {
let key = Defaults.Key<Bool>("observeKey", default: false)
let expect = expectation(description: "Observation closure being called")
Expand Down

0 comments on commit 3275717

Please sign in to comment.