1
votes

I am having troubles with running view methods on published property value change. My playground sample code looks like this:

class MyFoo: ObservableObject {
    @Published var bar: String
    init(bar: String) {
        self.bar = bar
    }

    func setNewText(newString: String) {
        self.bar = newString
    }

    func runFunctions() {
        setNewText(newString: "Test")
    }
}

struct TestView: View {
    @ObservedObject let foo = MyFoo(bar: "bar0")

    init(){
        let barSink = foo.$bar
            .sink() { //THIS IS WHERE I GET ERROR "Escaping closure captures mutating 'self' parameter"
                self.printResult(result: $0)
            }
    }

    func printResult(result: String) {
        print(result)
    }
}

let a = TestView()

Basically I know why I get this error in closure but I don't know how to go around it. Is this the right approach for running view methods on VM published property value changed?

I need this because I am using custom spinner that is not SwiftUI ready so I cant bind to it, and the only way to show/hide it is by calling its methods.

Any help would be most appreciated

1
try adding @ObservedObject before let foo = MyFoo(bar: "bar0") and make MyFoo inherit from ObservableObject: class MyFoo: ObservableObject {} - krjw
I have edited the question, but it doesn't fix the error - AntonijoDev

1 Answers

2
votes

I don't know how the playground works but I try to answer you question. I tested the code in the simulator and on a real device:


class MyFoo: ObservableObject {
    @Published var bar: String
    init(bar: String) {
        self.bar = bar
    }

    func setNewText(newString: String) {
        self.bar = newString
    }

    func runFunctions() {
        setNewText(newString: "Test")
    }


}

struct TestView: View {
    @ObservedObject var foo = MyFoo(bar: "bar0")

    var body: some View {
        Text("Lolz")
            .onReceive(self.foo.$bar, perform: { lolz in
                self.printResult(result: lolz)
            })
    }

    func printResult(result: String) {
        print(result)
    }

}

struct ContentView: View {
    var body: some View {
        TestView()
    }
}

The @ObservedObject needs to be a var. With onRecieve() you can listen to the publisher and update UI or call a function.

I hope this helps.