删除 CoreData 实体中的所有记录

Posted

技术标签:

【中文标题】删除 CoreData 实体中的所有记录【英文标题】:Remove all record in CoreData Entity 【发布时间】:2020-06-29 05:35:28 【问题描述】:

我正在尝试使用 SwiftUI 在我的应用中实现 CoreData。

我创建了具有两个属性 icaoAPTiataAPT 的实体 Aeroporti

我的应用从 Firebase 数据库下载一些数据并将数据保存在本地以供离线使用。

我设法将所有数据保存在实体 Aeroporti 中,但现在我想创建一个函数来删除所有存储的数据,然后用户再次下载更新的数据。

我设法使用 func cancella() 直接在 contentView 中删除单个索引处的数据。

但现在我在 DataManager 中遇到了 func delate all 的问题。


import SwiftUI
import CoreData

struct ContentView: View 
    @ObservedObject var dm : DataManager
    @Environment(\.managedObjectContext) var managedObjectContext
    
    @FetchRequest(entity: Aeroporti.entity(),
                  sortDescriptors: [NSSortDescriptor(keyPath: \Aeroporti.iataAPT, ascending: true)]) var aeroport : FetchedResults<Aeroporti> // crea la variabile che contiene le ricette
   
    var body: some View 
        VStack
              HStack
                
                Button(action: 
                    DataManager.shared.downloadData(dbCore: self.managedObjectContext)
                ) 
                    Text("save from manager")
                
                
                Spacer()
                
                Button(action: 
                    DataManager.shared.delateALL(dbCore: self.managedObjectContext)
                ) 
                    Text("del all")
                
                
                
            
        List
          
            ForEach(aeroport, id: \.self)  apt in
                VStack
                Text(apt.iataAPT ?? "sconosciuto")
                Text(apt.icaoAPT ?? "sconosciuto")
                
            
            .onDelete(perform: cancella)
        
        
    
    
    
    // this delate at single index
    func cancella(at offset : IndexSet)  //1 ricevo indice ricetta , indexset è un array di indici
           
           for index in offset  // 2 ciclo dentro l'array offset con dentro gli indici
              let apt = aeroport[index] // 3 tiro furoi la ricetta a quel indice
               
               managedObjectContext.delete(apt) // 7 cancella alla fine la ricetta
           
           do  // 8 salvo
               try self.managedObjectContext.save()
              
              
            catch 
               debugPrint(error.localizedDescription)
           
       

我想删除实体 Aeroporti 中的所有记录,我试图写这个,但我当然卡住了:

class DataManager:  ObservableObject 
    
    let objectWillChange = PassthroughSubject<Void, Never>()
    let db = Firestore.firestore()
    static let shared = DataManager()
    

    
    // get data from Firestore and Save locally
    func downloadData(dbCore: NSManagedObjectContext ) 
    
            db.collection("VHHH").document("VHHHid").getDocument  (document, error) in
                if error == nil 
                    if document != nil && document!.exists  
    
                        let data = document!.data()

    
                        let icaoAPT = data?["icaoAPT"] ?? "empty"
                        let iataAPT = data?["iataAPT"] ?? "empty"
    
                        let aeroporto = Aeroporti(context: dbCore)
                        aeroporto.icaoAPT = icaoAPT as? String
                        aeroporto.iataAPT = iataAPT as? String
    
                        debugPrint(aeroporto.iataAPT!)
                        
                        do 
                            try dbCore.save()
                            print("Saved Data")
                         catch 
                            
                            let nserror = error as NSError
                            fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
                        
                    
                
            
        
    

    // test delate all...NOT WORKING
    func delateALL(dbCore: NSManagedObjectContext, vett: FetchedResults<NSFetchRequestResult>)
 
//        let req = NSFetchRequest<NSFetchRequestResult>(entityName: "Aeroporti")
        
         // 3 tiro furoi la ricetta a quel indice
        for data in vett 
          let data1 = vett[0]
//            dbCore.delete(data1)
        
    

    // delate all but not update
//    func delateALL2(dbCore: NSManagedObjectContext)
//        let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Aeroporti")
//        let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
//
//
//        do 
//            try dbCore.execute(deleteRequest)
//            debugPrint("canx all")
//
//            do 
//                try dbCore.save()
//                print("Saved Data")
//             catch 
//
//                let nserror = error as NSError
//                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
//            
//
//         catch let error as NSError 
//            debugPrint(error)
//        
//
//    


谢谢你的帮助

【问题讨论】:

【参考方案1】:
func deleteRecords() 
        // References to context
        let context = App.persistency.container.viewContext

        let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "Aeroporti")
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)

        do 
            try context.persistentStoreCoordinator?.execute(deleteRequest, with: context)
         catch let error as NSError 
            print("Fetch failed. \(error.localizedDescription)")
        
    

为了更新您的 UI,您可以进行如下操作:

    创建一个@State private var airportCount: Int? 在您的 body content 中,添加一个 onAppear(_:) 修饰符,并在加载视图后将您在数据库中的正确机场总数添加到 airportCount。 当您调用方法 deleteRecords() 时,请务必使用新数字 (0) 更新您的 airportCount 变量,您的视图将会更新。

就是这样。视图应该重新加载。

【讨论】:

它可以工作,但是 contentView 没有立即更新.. 只有在重新启动应用程序后才会为空 哦,好吧,我编辑我的答案是为了更新 UI。实现视图更新的方法有很多,但是这个比较简单。

以上是关于删除 CoreData 实体中的所有记录的主要内容,如果未能解决你的问题,请参考以下文章

Core Data + iCloud,更改通知插入和删除关系中的对象但不更新关系中现有实体的属性

Core Data 删除外部存储实体不会释放 iCloud 中的空间

当我删除相关对象时,为啥 Core Data 会复活已删除的对象?

Core Data 中父实体的计算属性

在 Core Data 中创建关系以执行删除

在 Core Data 中为实体添加属性