【问题标题】:iOS: Delete ALL Core Data SwiftiOS:删除所有核心数据 Swift
【发布时间】:2014-08-30 18:31:17
【问题描述】:

我对如何快速删除所有核心数据感到有些困惑。我创建了一个带有IBAction 链接的按钮。单击按钮后,我有以下内容:

let appDel: foodforteethAppDelegate = UIApplication.sharedApplication().delegate as foodforteethAppDelegate
    let context: NSManagedObjectContext = appDel.managedObjectContext

然后我搞砸了各种方法来尝试删除所有核心数据内容,但我似乎无法让它工作。我已经使用 removeAll 从存储的数组中删除,但仍然无法从核心数据中删除。我假设我需要某种类型的 for 循环,但不确定如何从请求中实现它。

我尝试过应用删除单行的基本原理

func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath!) {

    let appDel: foodforteethAppDelegate = UIApplication.sharedApplication().delegate as foodforteethAppDelegate
    let context:NSManagedObjectContext = appDel.managedObjectContext

    if editingStyle == UITableViewCellEditingStyle.Delete {

        if let tv = tblTasks {
            context.deleteObject(myList[indexPath!.row] as NSManagedObject)
            myList.removeAtIndex(indexPath!.row)
            tv.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: UITableViewRowAnimation.Fade)
        }

        var error: NSError? = nil
        if !context.save(&error) {
            abort()
        }

    }

}

但是,这样做的问题是,当我单击按钮时,我没有 indexPath 值,而且我需要遍历所有我似乎无法与上下文相关的值。

【问题讨论】:

标签: ios swift core-data


【解决方案1】:

试试这个简单的解决方案:

func deleteAllData(entity: String)
{
    let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    let managedContext = appDelegate.managedObjectContext
    let fetchRequest = NSFetchRequest(entityName: entity)
    fetchRequest.returnsObjectsAsFaults = false

    do 
    {
        let results = try managedContext.executeFetchRequest(fetchRequest)
        for managedObject in results
        {
            let managedObjectData:NSManagedObject = managedObject as! NSManagedObject
            managedContext.deleteObject(managedObjectData)
        }
    } catch let error as NSError {
        print("Detele all data in \(entity) error : \(error) \(error.userInfo)")
    }
}

斯威夫特 4

func deleteAllData(_ entity:String) {
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
    fetchRequest.returnsObjectsAsFaults = false
    do {
        let results = try dataController.viewContext.fetch(fetchRequest)
        for object in results {
            guard let objectData = object as? NSManagedObject else {continue}
            dataController.viewContext.delete(objectData)
        }
    } catch let error {
        print("Detele all data in \(entity) error :", error)
    }
}

实施:

 self.deleteAllData("your_entityName")

【讨论】:

  • @SVMrajech,请分享这个函数用于 swift 1.2
  • 不正确答案:删除核心数据并不意味着它只包含单个实体
  • 使用未解析的标识符“dataController”;你的意思是“tabBarController”吗?
【解决方案2】:

您可以从 iOS 9.0Swift 3 开始使用 destroyPersistentStore

public func clearDatabase() {
    guard let url = persistentContainer.persistentStoreDescriptions.first?.url else { return }
    
    let persistentStoreCoordinator = persistentContainer.persistentStoreCoordinator

     do {
         try persistentStoreCoordinator.destroyPersistentStore(at:url, ofType: NSSQLiteStoreType, options: nil)
         try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil)
     } catch {
         print("Attempted to clear persistent store: " + error.localizedDescription)
     }
}

【讨论】:

  • 你好,这工作得很好,但是如果我们将 CoreData 与 CloudKit 一起使用,这不会删除 CloudKit 数据,你能给我解决方案吗?
  • 这是迄今为止重置整个内容并删除所有实体中所有存储项目的最优雅的解决方案。 url 只是一个小改动! - url,因为这个变量在guard之后不再是可选的。
【解决方案3】:

要删除所有数据,您可以使用 NSBatchDeleteRequest

func deleteAllData(entity: String)
{
    let ReqVar = NSFetchRequest(entityName: entity)
    let DelAllReqVar = NSBatchDeleteRequest(fetchRequest: ReqVar)
    do { try ContxtVar.executeRequest(DelAllReqVar) }
    catch { print(error) }
}

【讨论】:

  • 出现错误。批量删除不支持删除规则
【解决方案4】:

我已经用下面的方法让它工作了:

@IBAction func btnDelTask_Click(sender: UIButton){

    let appDel: foodforteethAppDelegate = UIApplication.sharedApplication().delegate as foodforteethAppDelegate
    let context: NSManagedObjectContext = appDel.managedObjectContext  
    let request = NSFetchRequest(entityName: "Food")

    myList = context.executeFetchRequest(request, error: nil)


    if let tv = tblTasks {

        var bas: NSManagedObject!

        for bas: AnyObject in myList
        {
           context.deleteObject(bas as NSManagedObject)
        }

        myList.removeAll(keepCapacity: false)

        tv.reloadData()
        context.save(nil)
    }
}

但是,我不确定这是否是最好的方法。我还收到一个“常量 'bas' 推断有任何对象”错误 - 所以如果有任何解决方案,那就太好了

编辑

通过更改为 bas: AnyObject 修复

【讨论】:

  • 我遇到了这个错误Immutable value of type '[NSManagedObject]' only has mutating members named 'removeAll',不能在这里使用 removeall 吗?
  • 我相信这行是不需要的,因为我的代码在没有它的情况下按预期运行。 @TomSawyer
【解决方案5】:

Swift 3.0

func DeleteAllData(){


    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let managedContext = appDelegate.persistentContainer.viewContext
    let DelAllReqVar = NSBatchDeleteRequest(fetchRequest: NSFetchRequest<NSFetchRequestResult>(entityName: "Entity"))
    do {
        try managedContext.execute(DelAllReqVar)
    }
    catch {
        print(error)
    }
}

【讨论】:

    【解决方案6】:

    这是我在 Swift 3 中清除所有核心数据的实现,基于 Jayant Dash 的出色(和全面)答案。由于仅支持 iOS10+,因此更简单。它会删除所有核心数据实体,而无需对其进行硬编码。

    public func clearAllCoreData() {
        let entities = self.persistentContainer.managedObjectModel.entities
        entities.flatMap({ $0.name }).forEach(clearDeepObjectEntity)
    }
    
    private func clearDeepObjectEntity(_ entity: String) {
        let context = self.persistentContainer.viewContext
    
        let deleteFetch = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: deleteFetch)
    
        do {
            try context.execute(deleteRequest)
            try context.save()
        } catch {
            print ("There was an error")
        }
    }
    

    【讨论】:

    • 你不需要 context.save()
    【解决方案7】:

    在 Swift 3.0 中

     func deleteAllRecords() {
            //delete all data
            let context = appDelegate.persistentContainer.viewContext
    
            let deleteFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "YourClassName")
            let deleteRequest = NSBatchDeleteRequest(fetchRequest: deleteFetch)
    
            do {
                try context.execute(deleteRequest)
                try context.save()
            } catch {
                print ("There was an error")
            }
        }
    

    【讨论】:

      【解决方案8】:

      斯威夫特 5.1

      这里的大多数帖子都建议创建一个函数来按 name 删除所有实体,然后按名称删除所有实体。像这样:

      resetEntity(named: "MyEntity1")
      resetEntity(named: "MyEntity2")
      resetEntity(named: "MyEntity3")
      ...
      

      但是如果真正的问题是如何一次性清理所有 CoreData 实体,我建议您遍历实体名称:

      // Supposing this is a CoreDataController/CoreDataStack class where you have access to `viewContext` and `persistantContainer`
      // Otherwise just pass the `persistantContainer` as a parameter, from which you can also retrieve the `viewContext` 
      func resetAllCoreData() {
      
           // get all entities and loop over them
           let entityNames = self.persistentContainer.managedObjectModel.entities.map({ $0.name!})
           entityNames.forEach { [weak self] entityName in   
              let deleteFetch = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
              let deleteRequest = NSBatchDeleteRequest(fetchRequest: deleteFetch)
      
              do {
                  try self?.context.execute(deleteRequest)
                  try self?.context.save()
              } catch {
                  // error
              }
          }
      }
      

      希望对你有帮助

      【讨论】:

        【解决方案9】:

        对于 Swift 4.0svmrajesh's answer 的修改版本……或者至少是 Xcode 在它为我运行之前将它变成了什么。)

        func deleteAllData(entity: String) {
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let managedContext = appDelegate.persistentContainer.viewContext
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
        fetchRequest.returnsObjectsAsFaults = false
        
        do
        {
            let results = try managedContext.fetch(fetchRequest)
            for managedObject in results
            {
                let managedObjectData:NSManagedObject = managedObject as! NSManagedObject
                managedContext.delete(managedObjectData)
            }
        } catch let error as NSError {
            print("Delete all data in \(entity) error : \(error) \(error.userInfo)")
        }
        }
        

        实施:

        deleteAllData(entity: "entityName")
        

        【讨论】:

          【解决方案10】:

          在 Swift 用户界面中

          当您在项目开始时选择核心数据时,持久性协调器将由 swift 在应用程序委托中自动创建。场景委托为托管上下文创建@environmentObject

          let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
          
          let contentView = ContentView().environment(\.managedObjectContext, context)
          

          在内容视图中创建 manageObjectContext 实例,并使用属性包装器 @FetchRequest 获取 fetchRequest 对象

          @Environment(\.managedObjectContext) var moc
          @FetchRequest(entity: EntityName.entity(), sortDescriptors: []) var entityNames: FetchedResults<EntityName>
          

          执行删除操作

          for entityName in entityNames {
          moc.delete(entityName)
          }
          try? moc.save()
          

          try 操作可能会抛出错误,因此请在生产代码中实现 do try catch 块以正确处理错误。

          【讨论】:

            【解决方案11】:

            此 clean() 方法将从 DataModel 中获取实体列表并清除所有数据。

            func deleteAll(entityName: String) -> Error? {
                        if #available(iOS 9.0, *) {
                            do {
                                let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
                                let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
                                try context.execute(batchDeleteRequest)
                            } catch {
                                return error
                            }
                            return nil
                        } else {
                            let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
                            fetchRequest.returnsObjectsAsFaults = false
                            do
                            {
                                let results = try context.fetch(fetchRequest)
                                for managedObject in results
                                {
                                    if let managedObjectData:NSManagedObject = managedObject as? NSManagedObject {
                                        context.delete(managedObjectData)
                                    }
                                }
                            } catch  {
                                return error
                            }
                            return nil
                        }
                    }
            
                    var objectModel: NSManagedObjectModel? {
                        if #available(iOS 10.0, *) {
                            return persistentContainer.managedObjectModel
                        } else {
                            return persistentStoreCoordinator?.managedObjectModel
                        }
                    }
            
                    open func clean() {
                        if let models = objectModel?.entities {
                            for entity in models {
                                if let entityName = entity.name {
                                    _ = deleteAll(entityName: entityName)
                                }
                            }
                        }
                    }
            

            编码愉快!

            【讨论】:

            • 欢迎来到 Stack Overflow!仅代码的答案不是很有帮助。请编辑您的答案,以解释您的代码解决原始问题的原因。
            【解决方案12】:

            斯威夫特 5.1

            let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
            let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
            
                    do {
                        try coreDataManager.managedObjectContext.execute(batchDeleteRequest)
                    } catch {
                        print("Detele all data in \(entityName) error :", error)
                    }
            

            【讨论】:

              【解决方案13】:

              据我所知有两种简单的方法,第一种

              方法一:

              获取、删除、重复

              //初始化获取请求

              let fetchRequest = NSFetchRequest(entityName: "Item")
              

              //配置获取请求

               fetchRequest.includesPropertyValues = false
              
              do {
              
              let items = try managedObjectContext.executeFetchRequest(fetchRequest) as! [NSManagedObject]
              
              for item in items {
                  managedObjectContext.deleteObject(item)
              }
              
              // Save Changes
              try managedObjectContext.save()
              
              } catch {
              // Error Handling
              // ...
              

              }

              方法二:

              批量删除请求

              // 创建获取请求

              let fetchRequest = NSFetchRequest(entityName: "Item")
              

              // 创建批量删除请求

                   let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
                     do {
                        try managedObjectContext.executeRequest(batchDeleteRequest)
              
                        } catch {
              // Error Handling
                  }
              

              我都测试过,它们都可以正常工作

              【讨论】:

                【解决方案14】:

                斯威夫特 5

                func deleteAllData(entity: String){
                
                guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
                let managedContext = appDelegate.persistentContainer.viewContext
                let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
                fetchRequest.returnsObjectsAsFaults = false
                
                do {
                    let arrUsrObj = try managedContext.fetch(fetchRequest)
                    for usrObj in arrUsrObj as! [NSManagedObject] {            
                        managedContext.delete(usrObj)
                    }
                   try managedContext.save() //don't forget
                    } catch let error as NSError {
                    print("delete fail--",error)
                  }
                
                }
                

                【讨论】:

                  【解决方案15】:

                  要删除 Core Data 中的所有条目,我找到了两种方法

                  1 - 带有for 函数

                  func deleteEntries() {
                      do {
                          let managedObjectContext = try CoreDataStack.sharedInstance.getContext()
                          for record in records {
                              managedObjectContext.delete(record)
                          }
                          try managedObjectContext.save()
                      } catch let error {
                          print(error.localizedDescription)
                      }
                  }
                  

                  2 - 带有NSBatchDeleteRequest

                  func deleteEntries() {
                      do {
                          let managedObjectContext = try CoreDataStack.sharedInstance.getContext()
                          let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Location")
                          let request: NSBatchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
                          try managedObjectContext.execute(request)
                          try managedObjectContext.save()
                      } catch let error {
                          print(error.localizedDescription)
                      }
                  }
                  

                  我建议使用数字 2,因为它是处理应用中资源的更好方法

                  【讨论】:

                    【解决方案16】:

                    另一种方法是完全删除并重新创建持久存储(iOS 10+,swift 3)。

                    let urls = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask);
                        var dbUrl = urls[urls.count-1];
                        dbUrl = dbUrl.appendingPathComponent("Application Support/nameOfYourCoredataFile.sqlite")
                        do {
                            try persistentContainer.persistentStoreCoordinator.destroyPersistentStore(at: dbUrl, ofType: NSSQLiteStoreType, options: nil);
                        } catch {
                            print(error);
                        }
                        do {
                            try persistentContainer.persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: dbUrl, options: nil);
                        } catch {
                            print(error);
                        }
                    

                    【讨论】:

                      【解决方案17】:

                      我用这个来删除Swift3中的所有核心数据实体

                      func deleteAllCD(){
                          for entityName in ["EntityName", "AnotherEntityName"]{
                              let request = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
                              let delAllReqVar = NSBatchDeleteRequest(fetchRequest: request)
                              do { try persistentContainer.viewContext.execute(delAllReqVar) }
                              catch { print(error) }
                          }
                      }
                      

                      【讨论】:

                      • 批量删除不支持删除规则
                      【解决方案18】:

                      斯威夫特 3

                      // Replace 'MyEntityName' with your managed object class.
                      let moc = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
                      let fetchRequest: NSFetchRequest<MyEntityName> = MyEntityName.fetchRequest()
                      fetchRequest.returnsObjectsAsFaults = false
                      moc.perform {
                          do {
                              let myEntities = try fetchRequest.execute()
                              for myEntity in myEntities {
                                  moc.delete(myEntity)
                              }
                              try moc.save()
                          } catch let error {
                              print("Delete Error: \(error.localizedDescription)")
                          }
                      }
                      

                      【讨论】:

                        【解决方案19】:

                        与上述类似,但取消了 AppDelegte 调用并使用了 UIView 变量

                        var context: NSManagedObjectContext?
                        //deleting Message
                        
                        func deleteMessages(entity: String) {
                           do {
                              let request = NSFetchRequest(entityName: entity)
                              print(request)
                        
                              if let result = try context!.executeFetchRequest(request) as? [your class of NSManagedObject] {
                                  for message in result {
                                     context!.deleteObject(message)
                                     try context!.save()
                                     print(message)
                                     self.tableView.reloadData()
                                  }
                              }
                           } catch {
                                 print("miss")
                           }
                        }
                        

                        使用通话功能

                        self.deleteMessages("TimeMaster")
                        

                        【讨论】:

                          【解决方案20】:

                          试试这个:

                          func deleteAllData(entity: String)
                          {
                              let appDelegate = UIApplication.shared.delegate as! AppDelegate
                              let context = appDelegate.persistentContainer.viewContext
                              let ReqVar = NSFetchRequest(entityName: entity)
                              let DelAllReqVar = NSBatchDeleteRequest(fetchRequest: ReqVar)
                              do { try ContxtVar.executeRequest(DelAllReqVar) }
                              catch { print(error) }
                          }
                          

                          【讨论】:

                            【解决方案21】:

                            斯威夫特 4:

                            destroyPersistentStoreAtURL(_:withType:options:) 将删除(或截断)目标持久存储。这将安全地销毁持久存储。

                            添加:

                            do {
                                try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: persistentStoreURL, options: nil)
                            } catch {
                                // Error Handling
                            }
                            

                            销毁/删除/截断:

                            do {
                                try persistentStoreCoordinator.destroyPersistentStoreAtURL(persistentStoreURL, withType: NSSQLiteStoreType, options: nil)
                            } catch {
                                // Error Handling
                            }
                            

                            注意:上述方法中的参数应与 addPersistentStoreWithType 方法相同。 您需要重新启动 storeCoordinator 才能再次使用 store。

                            【讨论】:

                            • 似乎并没有真正删除数据库文件本身,我还需要调用FileManager.default.removeItem(at: )
                            【解决方案22】:

                            对于 Swift 4.0

                              func deleteAllData(_ entity:String) {
                            
                                let managedContext =  DatabaseController.getContext().persistentStoreCoordinator
                                 let context = DatabaseController.getContext()
                                let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
                                let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
                                do {
                                    try managedContext?.execute(batchDeleteRequest, with: context)
                                }
                                catch {
                                    print(error)
                                }
                            
                            
                              }
                            

                            【讨论】:

                              【解决方案23】:

                              斯威夫特 4

                              从 iOS 9 开始,可以擦除持久存储。 为了更好地维护 - 创建具有 abstract 功能的 NSPersistentStoreCoordinator 扩展。

                              extension NSPersistentStoreCoordinator {
                                  func destroyPersistentStore(type: String) -> NSPersistentStore? {
                                      guard 
                                          let store = persistentStores.first(where: { $0.type == type }),
                                          let storeURL = store.url 
                                      else {
                                          return nil
                                      }
                              
                                      try? destroyPersistentStore(at: storeURL, ofType: store.type, options: nil)
                              
                                      return store
                                  }
                              }
                              

                              那么销毁 SQLite 持久存储看起来很简单:

                              let coordinator = persistentContainer.persistentStoreCoordinator
                              let store = coordinator.destroyPersistentStore(type: NSSQLiteStoreType)
                              

                              建议

                              1. 更新 destroyPersistentStore 函数,该函数不可为空并引发特定错误,例如 CoreDataError 枚举。
                              2. 您可能想要刷新持久性存储。为此,您可以使用 NSPersistentStoreCoordinatoraddPersistentStore 函数,并从 destroyPersistentStore 检索到 NSPersistentStore 对象。

                              【讨论】:

                                【解决方案24】:
                                static func fetch<T>(entity: T.Type, withPredicate predicate: NSPredicate? = nil) -> Array<T>? where T : NSManagedObject {
                                    let request: NSFetchRequest<T> = NSFetchRequest<T>(entityName: String(describing: T.self))
                                    request.predicate = predicate
                                    do {
                                        return try context.fetch(request)
                                    }catch{
                                        print(error.localizedDescription)
                                    }
                                    return nil
                                }
                                
                                 static func delete<T>(_ object: T) where T : NSManagedObject {
                                    context.delete(object)
                                    saveContext()
                                }
                                
                                static func reset<T>(entity: T.Type) where T : NSManagedObject {
                                    fetch(entity: entity.self)?.forEach{
                                        delete($0)
                                    }
                                
                                }
                                

                                【讨论】:

                                  猜你喜欢
                                  • 2017-02-16
                                  • 2016-10-27
                                  • 2017-08-12
                                  • 1970-01-01
                                  • 2017-03-20
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2013-09-04
                                  相关资源
                                  最近更新 更多