【发布时间】:2021-08-16 13:44:33
【问题描述】:
在以下代码中,我有一个Cars 的List,并且该列表中的每个Car 都有自己的Services 列表,我可以通过调用添加和删除Cars 而不会出现问题carViewModel.addNewCar(make:String, model:String) 和 carViewModel.deleteCar(at indexSet:IndexSet)。
汽车.swift
import RealmSwift
final class Car: Object, ObjectKeyIdentifiable{
@objc dynamic var make: String = ""
@objc dynamic var model: String = ""
// creation date, ID etc.
dynamic var services = List<CarService>()
}
CarList.swift
import RealmSwift
final class CarList: Object, ObjectKeyIdentifiable{
@objc dynamic var name: String = ""
// creation date, ID etc.
var cars = RealmSwift.List<Car>()
}
CarService.swift
import RealmSwift
final class CarService: Object, ObjectKeyIdentifiable{
@objc dynamic var serviceName: String = ""
// creation date, ID etc.
}
查看模型
import RealmSwift
class CarViewModel: ObservableObject{
@Published var cars = List<Car>()
@Published var selectedCarList: CarList? = nil
var token: NotificationToken? = nil
init(){
// Create a the default lists if they don't already exist.
createDefaultCarList()
createDefaultServiceList()
// Initialize the SelectedCarList and the cars variables items from the Default Car List.
if let list = realm?.objects(CarList.self).first{
self.selectedCarList = list
self.cars = list.cars
}
token = selectedCarList?.observe({ [unowned self] (changes) in
switch changes{
case .error(_): break
case.change(_, _):self.objectWillChange.send()
case.deleted: self.selectedCarList = nil
}
})
}
func addNewCar(make:String, model:String){
if let realm = selectedCarList?.realm{
try? realm.write{
let car = Car()
car.make = make
car.model = model
selectedCarList?.cars.append(car)
}
}
}
func deleteCar(at indexSet:IndexSet){
if let index = indexSet.first,
let realm = cars[index].realm{
try? realm.write{
realm.delete(cars[index])
}
}
}
func addService(toCar: Car, serviceName: String){
try? realm?.write{
let service = CarService()
service.serviceName = serviceName
toCar.services.append(service)
}
}
/// Creates the Default Car List if it doesn't already exists otherwise just prints the error.
func createDefaultCarList(){
do {
if (realm?.objects(CarList.self).first) == nil{
try realm?.write({
let defaultList = CarList()
defaultList.name = "Default Car List"
realm?.add(defaultList)
})
}
}catch let error{
print(error.localizedDescription)
}
}
/// Creates the Default Serivice List if it doesn't already exists otherwise just prints the error.
func createDefaultServiceList(){
do {
if (realm?.objects(ServiceList.self).first) == nil{
try realm?.write({
let defaultList = ServiceList()
defaultList.listName = "Default Service List"
realm?.add(defaultList)
})
}
}catch let error{
print(error.localizedDescription)
}
}
}
我的问题是将Services 添加或删除到现有的Cars。当我致电carViewModel.addService(toCar: Car, serviceName: String) 时,我收到以下错误...
调用 addService() 方法。
struct NewServiceFormView: View {
@ObservedObject var carViewModel: CarViewModel
@State var selectedCar:Car // pass from other cars view
var body: some View {
NavigationView {
Form {
// fields
}
.navigationBarItems( trailing:Button("Save", action: addNewCar))
}
}
func addNewCar(){
carViewModel.addService(toCar: selectedCar, serviceName: "Oil Change")
}
}
错误
“无法在写入事务之外修改托管 RLMArray。”
我可以通过从cars 列表中明确选择Car 来添加新的Services。我没有收到任何错误,但 UI 没有更新;在应用重新启动之前,我看不到新添加的服务。
这样做没有错误,但 UI 不会更新。
carViewModel.addService(toCar: carViewModel.cars[1], serviceName: "Rotors")
如何正确查看、删除Services 并将其添加到现有Cars?
编辑:根据Mahan 的请求添加了以下代码。
View 呈现 NewServiceFormView
struct CarServicesView: View {
@State var selectedCar:Car // a car from parent view
@ObservedObject var carViewModel: CarViewModel
var body: some View {
VStack{
List {
Section(header: Text("Services: \(selectedCar.services.count)")) {
ForEach(selectedCar.services) { service in
}
}
}
.listStyle(GroupedListStyle())
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: openNewServiceForm) {
Image(systemName: "plus")
}
}
}
}.sheet(isPresented: $newServiceFormIsPresented){
NewServiceFormView(carViewModel: carViewModel, selectedCar: selectedCar)
}
}
func openNewServiceForm() {
newServiceFormIsPresented.toggle()
}
}
【问题讨论】:
-
能否将您使用过
NewServiceFormView的视图包含在其中? -
在父视图中我刚刚提出了
NewServiceFormView.sheet(isPresented: $newServiceFormIsPresented){ NewServiceFormView(carViewModel: carViewModel, selectedCar: selectedCar) }谢谢。 -
@mahan - 查看更新的代码。谢谢。
标签: swiftui realm combine realm-list