amok
amok

Reputation: 1745

UIHostingController throws

I want to load from a UIViewController a SwiftUI based view that reads a json local to the bundle. The code and binding in a swiftUI only project works fine, when I leverage the UIHostingController I get an error for which I am seeking help to fix.

class ProgramsListVCHost : UIHostingController<ProgramsList>, Storyboarded {
    weak var coordinator: MainCoordinator?

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder, rootView: ProgramsList())

    }
}

The code above crashes because I didn't pass what I should have to cause the init of the model.

super.init(coder: aDecoder, rootView: ProgramsList().environmentObject(ProgramUserData()))

However, if I do that the compiler demands that I cast the whole thing to the underlying class ProgramList (Cannot convert value of type 'some View' to expected argument type 'ProgramsList')

If I do apply the recommended fix, the code crashes with the error:

Could not cast value of type 'SwiftUI.ModifiedContent>>' (0x7fff89d0ec68) to 'bikeit.ProgramsList' (0x110477328). 2019-11-15 14:36:26.049041-0500 bikeit[13658:8386085] Could not cast value of type 'SwiftUI.ModifiedContent>>' (0x7fff89d0ec68) to 'bikeit.ProgramsList' (0x110477328). (lldb)

I don't understand how to initialize the object that I must pass in order to make it work.

Upvotes: 5

Views: 1035

Answers (1)

Asperi
Asperi

Reputation: 257663

Of course, it is because your declared content UIHostingController<ProgramsList> is ProgramsList, so it is expected in initialiser, but you pass to it output of .environmentObject, which is SwiftUI.ModifiedContent, so types checking fails and you get compiler error.

It is not clear your needs, but possible solution could be as follows:

class ProgramsListVCHost : UIHostingController<AnyView>, Storyboarded {
    weak var coordinator: MainCoordinator?

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder, rootView: AnyView(ProgramsList().environmentObject(ProgramUserData())))
    }
}

Update: found alternate

class ProgramsListVCHost : UIHostingController<ProgramsListVCHost.MyView>, Storyboarded {

    // Internal view
    struct MyView: View {
      var body: some View {
         ProgramsList().environmentObject(ProgramUserData())
      }
    }

    weak var coordinator: MainCoordinator?

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder, rootView: MyView())
    }
}

Upvotes: 6

Related Questions