Как создать экземпляр UIHostingController с помощью CoreData?
Как давний разработчик Obj-C (начиная с iPhone OS 2), я решил, что SwiftUI - это толчок к использованию Swift! ¯\(ツ)/¯ Таким образом, я все еще пытаюсь понять, как язык может быть таким расплывчатым в коде и таким педантичным в компиляторе!!!
Вытаскиваю волосы, пытаясь заставить Swift/SwiftUI создать экземпляр UIHostingController<> для использования с 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")
}
}
Как я могу заставить Swift ВЫВОДИТЬ правильный / подходящий тип?
То, что я пробовал до сих пор.
5 let contentView = MyCoreDataView()
Компилирует / запускает, но не включает CoreData.
6 super.init(coder: coder, rootView: contentView as! MyCoreDataView)
Компилируется, но вылетает при создании экземпляра.
Не удалось привести значение типа SwiftUI.ModifiedContent
> (...) к MyHostingController.MyCoreDataView (...).
... или это просто невозможно? (пока что)
2 ответа
Вот самый быстрый приходят в ум решение - просто использоватьAnyView
шрифт-ластик.
Примечание: любой модификатор представления создает (может вообще создавать) разные типы представления, поэтому в вашем случае компилятор жалуется - типы разные.
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))
}
}
Автор: OOPer на форумах Apple Dev:
Как видите, модификаторы для SwiftUI View возвращают какой-то непрозрачный тип some View, который не раскрывается программистам, но компилятор Swift утверждает, что тип везде соответствует типу...
Одно из возможных решений - создать оболочку View:
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)
}
}
Или вы можете выбрать AnyView в качестве оболочки:
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)
}
}
Я не уверен, работает ли это в вашем случае, но попробуйте.