Closed emadhegab closed 7 months ago
This is an issue with @Observable.
"In the current implementation, the @Observable macro requires that all stored properties have a default value. This helps observable types rely on definitive initialization, use the implicitly generated initializers, and define additional initializers in extensions."
You should, however, be able to get past the issue by doing something like...
@ObservationIgnored @Injected(\.loginService) private var loginService: LoginServicing
Also keep in mind that if you use @Observable your application can only run on iOS 17 and higher.
I did figure this out, even before seeing this, but I'm seeing a new issue that I wasn't having with ObservableObject
. My SwiftUI previews where I inject a preview object like:
struct WeatherAgeFooterView_Previews: PreviewProvider {
static var previews: some View {
let _ = Container.shared.weatherManager.register { WeatherManagerPreview() }
WeatherAgeFooterView()
}
}
is no longer working. In all my previews, I now get errors because they are running the Impl objects in my ViewModel
s instead of the preview objects I'm registering. This doesn't happen if I switch back to ObservableObject
(which I really don't want to do because of the performance benefits to @Observable
).
EDIT: I'd also be interested in a documentation section on how to get Factory injection like the above working with #Preview
...if that's even possible.
I think your problem is elsewhere, as the following works...
import Factory
#if canImport(Observation)
import Observation
#endif
import SwiftUI
@available(iOS 17, *)
protocol ObservationServiceType: AnyObject {
var name: String { get set }
}
@available(iOS 17, *)
@Observable
class ObservationService: ObservationServiceType {
var name: String = "ObservationService"
}
@available(iOS 17, *)
@Observable
class MockObservationService: ObservationServiceType {
var name: String = "MockObservationService"
}
@available(iOS 17, *)
extension Container {
var observableService: Factory<ObservationServiceType> {
self { ObservationService() }
}
}
@available(iOS 17, *)
struct ObservableView: View {
@Injected(\.observableService) var observableService
var body: some View {
HStack {
Text(observableService.name)
Spacer()
Button("Mutate") {
observableService.name += " *"
}
}
.padding()
}
}
@available(iOS 17, *)
#Preview {
let _ = Container.shared.observableService.register { MockObservationService() }
return ObservableView()
}
Okay, I tested this myself, and you're correct, it works. I have no idea why my previews are now using the default Impl versions and not preview versions of my services, but it doesn't appear to be what I thought it was.
Are there any plans to support @Bindable with @Injected wrapper so bindings are available for use in Publisher Combinators
in a model where i use @Observable macro ,
i get 2 errors at the Injected vars