iOS 17 introduced @Observable. that's an effective way to implement a stateful model object.
however, we will not be able to use @StateObject as the model object does not have ObservableObject protocol. An advantage of using StateObject is able to make the object initializing once only for the view. it will keep going on until the view identifier is changed.
I put some examples. We have a Observable implemented object.
@Observable final class Controller { ... }
then using like this
struct MyView: View {
let controller: Controller
init(value: Value) {
self.controller = .init(value: value)
}
init(controller: Controller) {
self.controller = controller
}
}
this case causes a problem that the view body uses the passed controller anyway. even passed different controller, uses it.
and what if initializing a controller takes some costs, that decrease performance.
how do we manage this kind of use case?
anyway I made a utility view that provides an observable object lazily.
public struct ObjectProvider<Object, Content: View>: View {
@State private var object: Object?
private let _objectInitializer: () -> Object
private let _content: (Object) -> Content
public init(object: @autoclosure @escaping () -> Object, @ViewBuilder content: @escaping (Object) -> Content) {
self._objectInitializer = object
self._content = content
}
public var body: some View {
Group {
if let object = object {
_content(object)
}
}
.onAppear {
object = _objectInitializer()
}
}
}
ObjectProvider(object: Controller() { controller in
MyView(controller: controller)
}
for now it's working correctly.