SwiftUI и модели данных (CoreData) - Как изменить данные? - PullRequest
0 голосов
/ 07 апреля 2020

Я очень запутался в том, как использовать 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

...