As a long-time Obj-C dev (since iPhone OS 2) I decided that SwiftUI was the nudge to use Swift! ¯\(ツ)/¯ Thus, I am still trying to understand how a language can be so type-vague in code, and so type-pedantic in the compiler!!!
Pulling my hair out trying to get Swift/SwiftUI to instantiate a UIHostingController<>, for use with CoreData
class MyCoreDataHostingController : UIHostingController<MyCoreDataView> {
required init?(coder: NSCoder) {//Instantiate From Storyboard
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let contentView = MyCoreDataView().environment(\.managedObjectContext, context)
super.init(coder: coder, rootView: contentView)
//Cannot convert value of type 'some View' to expected argument type 'MyCoreDataView'
}
}
struct MyCoreDataView: View {
var body: some View {
Text("Core Data View")
}
}
How can I FORCE Swift to INFER the correct/appropriate type?
What I have tried so far.
5 let contentView = MyCoreDataView()
Compiles/runs, but does not include CoreData.
6 super.init(coder: coder, rootView: contentView as! MyCoreDataView)
Compiles, but crashes at instantiation.
Could not cast value of type 'SwiftUI.ModifiedContent<MyHostingController.MyCoreDataView, SwiftUI._EnvironmentKeyWritingModifier<__C.NSManagedObjectContext>>' (...) to 'MyHostingController.MyCoreDataView' (...).
... or is this simply not possible? (yet)
Here is the fastest come-in-mind solution - just use AnyView
type-eraser.
Note: any view modifier creates (can create in general) different type of view, that's why compiler complains in your case - types are different.
class MyCoreDataHostingController : UIHostingController<AnyView> {
required init?(coder: NSCoder) {//Instantiate From Storyboard
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let contentView = MyCoreDataView().environment(\.managedObjectContext, context)
super.init(coder: coder, rootView: AnyView(contentView))
}
}