Я очень запутался в том, как использовать Core Data
с SwiftUI
. Об этом написано множество статей, но все демонстрируют только те ситуации, которые отлично работают. Никто не показывает немного более сложные вещи, и я не могу понять это. Я пытался в течение двух недель. (Я могу кодировать его, чтобы заставить его просто работать; однако я пытаюсь найти хороший и прагматичный способ c, и с этим я борюсь).
Вот пример:
struct CarView: View {
@State var car: Car
struct Car {
let id: UUID = UUID()
let name: String
let price: Int
}
var body: some View {
VStack {
Text(car.name)
Text("\(car.price)")
}
}
}
struct CarView_Previews: PreviewProvider {
static var previews: some View {
CarView(car: .init(name: "Tesla Model X", price: 42))
}
}
Это совершенно простая конструкция, которая также легко тестируется и обрабатывается, потому что вы можете просто создать фиктивный Car
экземпляр для использования, например, XCode Previews.
Но что произойдет, если вы захотите добавить в нее модель данных, которая извлекает данные из базы данных? Скажем, у вас есть CarManagedObject
NSManagedObject
подкласс. Как бы вы связали это с нашим SwiftUI
View?
Вы можете просто заменить структуру Car
на подкласс CarManagedObject
, потому что он соответствует ObservableObject
. Так что-то вроде этого будет работать:
struct CarView: View {
@ObservedObject var car: CarManagedObject
...
}
Однако теперь мы тесно связали CarView
с Core Data
. Вы не можете использовать вид без него больше. Также сложно создавать фиктивные данные. Поэтому было бы лучше продолжать использовать Car
структуру, которая не зависит от всего. Это также то, что Apple делает в сеансе 233 WWD C 2019, начиная примерно с минуты 37: Session 23, WWD C 2019 .
Так что вы можете сделать это:
struct Car {
let id: UUID = UUID()
let name: String
let price: Int
static func create(from: CarManagedObject) -> Car {
...
}
}
Все это работает хорошо, пока у вас нет данных, которые могут измениться. Я не вижу хорошего способа обновления структуры при изменении базовых данных. Кроме того, мы полностью теряем возможность передавать Bindings
в подпредставления, потому что структура Car
не является фактическим источником данных. Изменение его не меняет модель данных.
Вы могли бы мучительно настроить его, используя Combine
в обоих направлениях, но это не кажется правильным. Я уверен, что SwiftUI
способен сделать это, я просто не понимаю, как.
У кого-нибудь есть идеи, как это сделать? Извините, если не совсем понятно, что я имею в виду. Я действительно смущен. Все это ломает мне голову: D