Updating a @Published variable based on changes in an observed variable

swiftui binding
swiftui published not working
swiftui environmentobject not updating
wrappedvalue is unavailable published is only available on properties of classes
swiftui nested observableobject
swiftui observer
swiftui passthroughsubject
swift binding vs published

I have an AppState that can be observed:

class AppState: ObservableObject {

    private init() {}
    static let shared = AppState()

    @Published fileprivate(set) var isLoggedIn = false

}

A View Model should decide which view to show based on the state (isLoggedIn):

class HostViewModel: ObservableObject, Identifiable {

    enum DisplayableContent {
        case welcome
        case navigationWrapper
    }

    @Published var containedView: DisplayableContent = AppState.shared.isLoggedIn ? .navigationWrapper : .welcome

}

In the end a HostView observes the containedView property and displays the correct view based on it.

My problem is that isLoggedIn is not being observed with the code above and I can't seem to figure out a way to do it. I'm quite sure that there is a simple way, but after 4 hours of trial & error I hope the community here can help me out.


DISCLAIMER:

It is not full solution to the problem, it won't trigger objectWillChange, so it's useless for ObservableObject. But it may be useful for some related problems.

Main idea is to create propertyWrapper that will update property value on change in linked Publisher:

@propertyWrapper
class Subscribed<Value, P: Publisher>: ObservableObject where P.Output == Value, P.Failure == Never {
    private var watcher: AnyCancellable?

    init(wrappedValue value: Value, _ publisher: P) {
        self.wrappedValue = value
        watcher = publisher.assign(to: \.wrappedValue, on: self)
    }

    @Published
    private(set) var wrappedValue: Value {
        willSet {
            objectWillChange.send()
        }
    }

    private(set) lazy var projectedValue = self.$wrappedValue
}

Usage:

class HostViewModel: ObservableObject, Identifiable {

    enum DisplayableContent {
        case welcome
        case navigationWrapper
    }

    @Subscribed(AppState.shared.$isLoggedIn.map({ $0 ? DisplayableContent.navigationWrapper : .welcome }))
    var contained: DisplayableContent = .welcome

    // each time `AppState.shared.isLoggedIn` changes, `contained` will change it's value
    // and there's no other way to change the value of `contained`
}

Manually publishing ObservableObject changes, To demonstrate this we're going to build an ObservableObject class that updates itself 10 times. You already met DispatchQueue.main.async() as  Possible duplicate of Updating a @Published variable based on changes in an observed variable – user28434 Oct 2 '19 at 14:43 1 Computed Properties are the kind of properties which are derived properties.


Working solution:

After two weeks of working with Combine I have now reworked my previous solution again (see edit history) and this is the best I could come up with now. It's still not exactly what I had in mind, because contained is not subscriber and publisher at the same time, but I think the AnyCancellable is always needed. If anyone knows a way to achieve my vision, please still let me know.

class HostViewModel: ObservableObject, Identifiable {

    @Published var contained: DisplayableContent
    private var containedUpdater: AnyCancellable?

    init() {
        self.contained = .welcome
        setupPipelines()
    }

    private func setupPipelines() {
        self.containedUpdater = AppState.shared.$isLoggedIn
            .map { $0 ? DisplayableContent.mainContent : .welcome }
            .assign(to: \.contained, on: self)
    }

}

extension HostViewModel {

    enum DisplayableContent {
        case welcome
        case mainContent
    }

}

Pass an @State variable to a Class so it can make changes to it , Pass an @State variable to a Class so it can make changes to it class Helper: ObservableObject { @Published var fieldBeingEdited: String = "" func Paul has some videos about the difference between State, Observed and Environment that are I had updated the question there to clarify my intent. Multiple Regression For Understanding Causes. A second use of multiple regression is to try to understand the functional relationships between the dependent and independent variables, to try to see what might be causing the variation in the dependent variable.


When you add an ObservedObject to a View, SwiftUI adds a receiver for the objectWillChange publisher and you need to do the same. As objectWillChange is sent before isLoggedIn changes it might be an idea to add a publisher that sends in its didSet. As you are interested in the initial value as well as changes a CurrentValueSubject<Bool, Never> is probably best. In your HostViewModel you then need to subscribe to AppState's new publisher and update containedView using the published value. Using assign can cause reference cycles so sink with a weak reference to self is best.

No code but it is very straight forward. The last trap to look out for is to save the returned value from sink to an AnyCancellable? otherwise your subscriber will disappear.

Learn SwiftUI: An introductory guide to creating intuitive , Just after the body variable is declared, we see the List property being used, which from within the PostViewMode class, changes that are published from within. be observed: class PostViewModel: ObservableObject { Now that might seem been updated with a new value, how does the SwiftUI know to reload the list? In other words, when one variable changes, it does not reflect in the change of the other variable in a linear way (Lecture 5 Notes, n.d., p. 1). For significance to be shown, it would have to be seen that the variables' values were statistically correlated in a manner that could be "represented in a linear equation" (Lecture 5 Notes, n.d., p. 1).


Three ways to react to @State event changes in SwiftUI, Three ways to react to @State event changes in SwiftUI In short time, I faced the challenge to update a @State variable based on another @State var textValue: String = "Hello" @Published var enteredTextValue: String  The National Climate Assessment summarizes the impacts of climate change on the United States, now and in the future. A team of more than 300 experts guided by a 60-member Federal Advisory Committee produced the report, which was extensively reviewed by the public and experts, including federal agencies and a panel of the National Academy of


How to modify state from state in SwiftUI - Fantageek, Modifying state during view update, this will cause undefined behavior. For example, when we get an image, we want to do some logic based on that image and modify result state. Note that we use $ prefix from a variable to form Binding that emits the changed value before any of its @published properties changes. Updating Data Values in a Table. You can use the UPDATE statement to modify data values in tables and in the tables that underlie PROC SQL and SAS/ACCESS views. For more information about updating views, see Updating a View. The UPDATE statement updates data in existing columns; it does not create new columns.


3 Ways to React to @State Changes in SwiftUI, 3 Ways to React to @State Changes in SwiftUI I quickly faced the challenge of updating an @State variable based on another @State variable's Published — A type that publishes a property marked with an attribute. A moderator variable is a variable involved in an interaction with another variable in the model such that the effect of the other variable depends upon the value of the moderator variable, i.e., the effect of the other variable changes depending on the value of the moderator.