I am trying to use environmentObject in a watchOS6 app to bind my data model to my view.
I have created a simple, stand-alone Watch app in Xcode 11.
I created a new DataModel class
import Combine import Foundation import SwiftUI final class DataModel: BindableObject { let didChange = PassthroughSubject<DataModel,Never>() var aString: String = "" { didSet { didChange.send(self) } } } In my ContentView struct I bind this class using @EnvironmentObject -
struct ContentView : View { @EnvironmentObject private var dataModel: DataModel var body: some View { Text($dataModel.aString.value) } } Finally, I attempt to inject an instance of the DataModel into the environment in the HostingController class -
class HostingController : WKHostingController<ContentView> { override var body: ContentView { return ContentView().environmentObject(DataModel()) } } But, I get an error:
Cannot convert return expression of type '_ModifiedContent<ContentView, _EnvironmentKeyWritingModifier<DataModel?>>' to return type 'ContentView' The error is because the WKHostingController is a generic that needs a concrete type - WKHostingController<ContentView> in this case.
A similar approach works perfectly with UIHostingController in an iOS app because UIHostingController isn't a generic class.
Is there some other way to inject the environment to a watchOS view?
You can use type erasure, AnyView in the case of SwiftUI View.
I would refactor WKHostingController to return AnyView.
This seems to compile fine on my end.
class HostingController : WKHostingController<AnyView> { override var body: AnyView { return AnyView(ContentView().environmentObject(DataModel())) } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With