Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using environmentObject in watchOS

Tags:

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?

like image 749
Paulw11 Avatar asked Jun 12 '19 06:06

Paulw11


1 Answers

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()))     } } 
like image 150
Matteo Pacini Avatar answered Oct 04 '22 15:10

Matteo Pacini