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
How can I FORCE Swift to INFER the correct/appropriate type?
What I have tried so far.
Compiles/runs, but does not include CoreData.
Compiles, but crashes at instantiation.
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
Code Block 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.
Code Block 5 let contentView = MyCoreDataView()
Compiles/runs, but does not include CoreData.
Code Block 6 super.init(coder: coder, rootView: contentView as! MyCoreDataView)
Compiles, but crashes at instantiation.
... or is this simply not possible? (yet)Could not cast value of type 'SwiftUI.ModifiedContent<MyHostingController.MyCoreDataView, SwiftUI.EnvironmentKeyWritingModifier<_C.NSManagedObjectContext>>' (...)
to 'MyHostingController.MyCoreDataView' (...).
As you see, modifiers for SwiftUI View returns some opaque type some View which is not revealed to programmers but Swift compiler claims matching the type every here and there...
One possible solution is creating a wrapper View:
Or you can choose AnyView as the wrapper:
I'm not sure if this works for your case, but please try.
One possible solution is creating a wrapper View:
Code Block class MyCoreDataHostingController : UIHostingController<MyCoreDataViewEnvironmentWrapper> { required init?(coder: NSCoder) {//Instantiate From Storyboard let contentView = MyCoreDataViewEnvironmentWrapper() super.init(coder: coder, rootView: contentView) } } struct MyCoreDataViewEnvironmentWrapper: View { private let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext var body: some View { MyCoreDataView().environment(\.managedObjectContext, context) } }
Or you can choose AnyView as the wrapper:
Code Block class MyCoreDataHostingController : UIHostingController<AnyView> { required init?(coder: NSCoder) {//Instantiate From Storyboard let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext let contentView = AnyView(MyCoreDataView().environment(\.managedObjectContext, context)) super.init(coder: coder, rootView: contentView) } }
I'm not sure if this works for your case, but please try.