核心数据和 SwiftUI

CoreData and SwiftUI

你好,我正在尝试为我的项目实现 Core Data 和 swiftUI。

我创建了一个名为 Aeroporti 的实体,它包含 2 个属性 iataAPT : String 和 icaoAPT: string。

我想保存简单的数据。

我这样设置应用委托:

  // MARK: - Core Data stack

    lazy var persistentContainer: NSPersistentContainer = {
        
        let container = NSPersistentContainer(name: "testFirebaseCoreData")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()

    // MARK: - Core Data Saving support

    func saveContext () {
        let context = persistentContainer.viewContext
        if context.hasChanges {
            do {
                try context.save()
            } catch {
                
                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
        }
    }

我的内容视图列出实体 Aeroporti 中的字段 icaoAPT

import SwiftUI
import CoreData

struct ContentView: View {
    @ObservedObject var dm : DataManager
    @Environment(\.managedObjectContext) var managedObjectContext
    @FetchRequest(entity: Aeroporti.entity(),
                  sortDescriptors: [NSSortDescriptor(keyPath: \Aeroporti.icaoAPT, ascending: true)]) var aeroport : FetchedResults<Aeroporti> // crea la variabile che contiene le ricette
   
    var body: some View {
        List{
            HStack{
                
               // NOT WORKING IF USING DataMANAGER
//                Button(action: {
//                    self.dm.provaSalva()
//                }) {
//                    Text("save from manager")
//                }
                
                saveFromView    // button save from view
            }
            ForEach(aeroport, id: \.self) { apt in
                Text(apt.icaoAPT ?? "sconosciuto")
//                    .environment(\.managedObjectContext, self.managedObjectContext)
            }
        }
        
    }
    
    var saveFromView : some View {
        
        Button(action: {
            let apt = Aeroporti(context: self.managedObjectContext)
            apt.iataAPT = "MFM"
            apt.icaoAPT = "VMMC"
            
            do {
                try self.managedObjectContext.save()
                print("airport saved.")
                
            } catch {
                print(error.localizedDescription)
            }
        }) {
            
            Text("save fromview")
        }
        
    }
}

一切正常,如果我使用 ContentView 中的按钮 (saveFromView),数据将被保存。

现在,为了更好地处理数据,我创建了一个 DataManager,我在其中放置了相同的代码以将数据保存在实体中,并且我尝试通过按钮(从经理)但它确实有效,我在保存时收到错误“操作无法完成。(Foundation._GenericObjCError 错误 0.)”。

import Combine
import SwiftUI
import CoreData


class DataManager:  ObservableObject {
    
    let objectWillChange = PassthroughSubject<Void, Never>()
    @Environment(\.managedObjectContext) var managedObjectContext
    
    
    func provaSalva() {
        let apt = Aeroporti(context: managedObjectContext)
        apt.iataAPT = "MFM"
        apt.icaoAPT = "VMMC"
        
        do {
            try self.managedObjectContext.save()
            print("airport saved.")
            
        } catch {
            print(error.localizedDescription)
        }
    }
    
    
}

问题是??为什么..是相同的代码...如果我想处理不在ContentView中的保存数据,我该如何解决这个问题。

感谢您的帮助..

通过将数据库传递给函数解决

 func provaSalva(dbCore: NSManagedObjectContext) {
        let apt = Aeroporti(context: dbCore)
        apt.iataAPT = "MFM"
        apt.icaoAPT = "VMMC"
        
        do {
            try dbCore.save()
            print("airport saved.")
            
        } catch {
            print(error.localizedDescription)
        }
    }

试一试。这是我用于我的应用程序的实现。

class DataManager {
    //MARK: - Setup
        
    //Singleton object
    static let defaults = DataManager()
    private init() {}
    
    //Managed object context
    var moc: NSManagedObjectContext {
        return (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    }
    
    //Save context, if changes were made
    func save() {
        if moc.hasChanges {
            do {
                print("Sucess!!")
                try moc.save()
            } catch {
                print("Error while saving managedObjectContext \(error)")
            }
        }
    }

    //MARK: - Insert

    //What you want to save
    func provaSalva() {
        let apt = Aeroporti(context: moc)
        apt.iataAPT = "MFM"
        apt.icaoAPT = "VMMC"
        
        save()
    }
}

你的saveFromView

var saveFromView : some View {
    Button(action: {
        DataManager.defaults.provaSalva()
    }) {
        Text("save fromview")
    }
}