jessesquires / Foil

A lightweight property wrapper for UserDefaults done right
https://jessesquires.github.io/Foil/
MIT License
459 stars 26 forks source link

Using UserDefaults Publisher? #4

Closed basememara closed 3 years ago

basememara commented 3 years ago

Is there a way to use the native UserDefaults.publisher added by Combine? It seems this only works if the properties were added as extensions to UserDefaults instead of a separate AppSettings type. For example, this test passes today:

func test_Integration_Publisher() {
    let promise = expectation(description: #function)
    var publishedValue: String?

    TestSettings.store
        .publisher(for: \.username, options: [.new])
        .sink {
            publishedValue = $0
            promise.fulfill()
        }
        .store(in: &cancellable)

    settings.username = "abc123"
    wait(for: [promise], timeout: 5)

    XCTAssertEqual(settings.username, publishedValue)
}

// This has to be added to get the publisher but of course duplicates the property already added to `TestSettings`
extension UserDefaults {
    @objc var username: String? {
        get { string(forKey: "username") }
        set { set(newValue, forKey: "username") }
    }
}

Since you cannot have more than one property wrapper on a field (I think), I'm wondering if WrappedDefault can offer a publisher on the property as well so instead of adding the property as an extension to UserDefaults, to be exposed from the same property that was created in TestSettings:

func test_Integration_Publisher() {
    let promise = expectation(description: #function)
    var publishedValue: String?

    settings.$username
        .publisher(options: [.new])
        .sink {
            publishedValue = $0
            promise.fulfill()
        }
        .store(in: &cancellable)

    settings.username = "abc123"
    wait(for: [promise], timeout: 5)

    XCTAssertEqual(settings.username, publishedValue)
}
basememara commented 3 years ago

Figured out how to use it without any code changes need to Foil 🎉

See PR #5 for added to readme and tests.

Thank you for a light and precise UserDefaults wrapper!

jessesquires commented 3 years ago

Thanks @basememara ! 💯

I'll try to review that PR later today 😊