Hello. I need a direction how SwiftUI work. And I assembled simple command line app:
import SwiftUI
struct Button {
@Binding var target: Int
func tap() {
target += 1
}
}
struct BindingApp {
func run() {
@State var target = 0
let button = Button(target: $target)
while true {
guard let _ = readLine() else { continue }
button.tap()
print("target: \(target)")
}
}
}
After run in terminal it prints:
d
target: 0
d
target: 0
It means that the variable @State var target = 0
in function run()
of struct BindingApp
does not receive any effect from instance of button
where it was passed. Why? Also I have another question. Why the method tap()
of Button
structure does not require to be mutating
despite the fact that it mutates its value property, as Binding is a structure. I would be grateful if you would drop me a lecture that explains what Binding is (a class or not:).
1 Like
@State
and other SwiftUI magic needs to be inflated to really work. It needs to be part of SwiftUI.View
or SwiftUI.Scene
, which in turn needs to be part of the hierarchy owned by HostingController
or @main
.
Under the hood, @State
has a two stored properties: one contains an initial value and never changes, and a second one contains a reference to Location
object which is initially nil
. When View
or Scene
is mounted, SwiftUI uses runtime metadata to find all the magical properties like @State
and initialize Location
. Setting value to @State
, changes it inside the Location
. But if location was never initialized, you will have only the initial value. I’m surprised SwiftUI does assert in this case.
I’m not 100% sure what you want to achieve, but I have a gut feeling that ObservableObject
will help you. It is part of Combine, and will work fine in command line app or in unit tests. And when you have UI, it will integrate with SwiftUI nicely.
Note that creating a Binding
to a property of the ObservableObject
from a reference stored in @ObservedObject
, @StateObject
or @EnvironmentObject
is still part of SwiftUI machinery and may not work outside hosted SwiftUI hierarchy.
3 Likes