Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] automatic trigger for objectWillChange publisher #5

Closed
BrentMifsud opened this issue Sep 8, 2022 · 2 comments · Fixed by #6
Closed

[Feature] automatic trigger for objectWillChange publisher #5

BrentMifsud opened this issue Sep 8, 2022 · 2 comments · Fixed by #6
Labels
enhancement New feature or request

Comments

@BrentMifsud
Copy link
Owner

BrentMifsud commented Sep 8, 2022

Remembering to add a willSet to all of your async value properties is not all that user friendly. I think we can do better:

Proposed Solution:

// this might not be needed with the new swift 5.7 generics. Will investigate. When Xcode 14 is released.
internal protocol AnyAsyncValue {
     var projectedValue: AsyncSequence<Any>
}

internal extension AsyncValue: AnyAsyncValue {
    var projectedValue: AsyncSequence<Any> {
        projectedValue
    }
}

@MainActor open class AsyncObservableObject: ObservableObject {
    private var objectWillChangeTasks: [Task<Void, Never>] = []
    
    init() {
         setupObjectWillChangeTasks()
    }

    deinit {
        for task in objectWillChangeTasks {
            task.cancel()
        }
    }

    private func setupObjectWillChangeTasks() {
        let mirror = Mirror(reflecting: self)

        for child in mirror.children {
              if let asyncValue = child.value as? AnyAsyncValue {
                  let task = Task {
                       for await _ in asyncValue.projectedValue {
                           objectWillChange.send()
                       }
                  }

                  objectWillChangeTasks.append(task)
              }
        } 
    }
}
@BrentMifsud BrentMifsud added help wanted Extra attention is needed good first issue Good for newcomers enhancement New feature or request and removed help wanted Extra attention is needed good first issue Good for newcomers labels Sep 8, 2022
jlsiewert added a commit to jlsiewert/AsyncValue that referenced this issue Sep 30, 2022
@jlsiewert
Copy link
Contributor

Turns out that is actually simple to to once you know how, since that does not seem to be documented anywhere but in the Swift Evolution Proposal.

Credit to SwiftBySundell for finding and writing about that.

The tldr of the implementation is that the implementation can provide an alternative built with a static subscript with a KeyPath to the enclosing instance of the wrapped property for class-types. Here, we further restrict that implementation to subclasses of ObservableObject that use the (default) ObservableObjectPublisher.

I have also changed the associated test case, seems to be working fine.

@BrentMifsud
Copy link
Owner Author

solved by #6

BrentMifsud pushed a commit that referenced this issue Oct 2, 2022
* Automatic trigger for objectWillChange publisher (implements #5)

* yield the value through the `didSet` implementation of the `wrappedValue` to respect the `behavior` property

* Dynamically check the objects type to allow the wrapper in non-`ObservableObject` types
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants