web-dev-qa-db-fra.com

iOS: Supprimer TOUTES les données de base Swift

Je suis un peu confus quant à la façon de supprimer toutes les données de base dans Swift. J'ai créé un bouton avec un lien IBAction. Sur le clic du bouton, j'ai les éléments suivants:

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

Ensuite, j'ai bricolé avec diverses méthodes pour essayer de supprimer tout le contenu de données de base, mais je n'arrive pas à le faire fonctionner. J'ai utilisé removeAll pour supprimer d'un tableau stocké mais je ne peux toujours pas supprimer des données de base. Je suppose que j'ai besoin d'un type de boucle for, mais je ne sais pas comment s'y prendre à partir de la requête. 

J'ai essayé d'appliquer le principe de base de la suppression d'une seule ligne

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()
        }

    }

}

Cependant, le problème avec ceci est que lorsque je clique sur un bouton, je n'ai pas la valeur indexPath et j'ai également besoin de parcourir toutes les valeurs que je ne peux pas sembler faire avec le contexte. 

47
Prateek

Je l'ai obtenu en utilisant la méthode suivante:

@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)
    }
}

Cependant, je ne suis pas sûr que ce soit la meilleure façon de s'y prendre. Je reçois également une erreur 'constante' supposée avoir une erreur 'quelconque' - donc s'il y a une solution à cela, ce serait génial

MODIFIER

Fixé en passant à bas: AnyObject

18
Prateek

Essayez cette solution simple:

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)")
    }
}

Swift 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)
    }
}

La mise en oeuvre:

 self.deleteAllData("your_entityName")
47
svmrajesh

Pour supprimer toutes les données, vous pouvez utiliser NSBatchDeleteRequest

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

Pour 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)
    }
}
12
anshul king

Cette méthode clean () va extraire la liste des entités de DataModel et effacer toutes les données.

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)
                    }
                }
            }
        }

Bon codage!

3
Jayant Dash

Pour Swift 4.0 (version modifiée de la réponse de svmrajesh … ou du moins ce que Xcode a transformé avant de pouvoir l'exécuter pour moi.)

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)")
}
}

La mise en oeuvre:

deleteAllData(entity: "entityName")
3
riherd

Dans 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")
        }
    }
2
Rob-4608

Il y a deux méthodes simples pour autant que je sache, d'abord 

Méthode 1: 

Récupérer, Supprimer, Répéter

// Initialise la requête de récupération

let fetchRequest = NSFetchRequest(entityName: "Item")

// Configurer la demande de récupération 

 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
// ...

}

Méthode 2: 

Demande de suppression par lot

// Créer une requête de récupération

let fetchRequest = NSFetchRequest(entityName: "Item")

// Créer une demande de suppression par lot

     let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
       do {
          try managedObjectContext.executeRequest(batchDeleteRequest)

          } catch {
// Error Handling
    }

J'ai testé les deux et ils fonctionnent tous les deux bien

1
raddaoui

Voici mon implémentation pour effacer toutes les données de base de Swift 3, basée sur l'excellente réponse (et complète) de Jayant Dash. Ceci est plus simple car supportant uniquement iOS10 +. Il supprime toutes les entités de données principales sans avoir à les coder en dur.

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")
    }
}
1
rmooney

Une autre solution consiste à supprimer et à recréer complètement le magasin persistant (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);
    }
1
grep

Vous pouvez essayer quelque chose comme ceci pour iOS 9.0+ et Swift 3+:

public func clearDatabase()
    {
        let url = persistentContainer.persistentStoreDescriptions.first?.url

        guard url != nil 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 let error {
            print(name.uppercased() + ": Clear store: " + error.localizedDescription)
        }
    }
0
gogoslab

Swift 4:  

destroyPersistentStoreAtURL (_: withType: options :) supprime (ou tronque) le magasin persistant cible. Cela va détruire en toute sécurité un magasin persistant.

Ajouter:

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

Détruire/Supprimer/Tronquer:

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

Remarque: Les paramètres de la méthode ci-dessus doivent être identiques à la méthode addPersistentStoreWithType. Vous devez relancer storeCoordinator pour utiliser store à nouveau.

0
Nikunj Joshi

Semblable à ci-dessus mais avec appel AppDelegte sorti et variable UIView utilisée

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")
   }
}

Pour utiliser la fonction d'appel

self.deleteMessages("TimeMaster")
0
gje4

J'utilise celui-ci pour supprimer toutes les entités de données de base dans 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) }
    }
}
0
Alexey Lysenko

Essaye ça: 

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) }
}
0
Farshid roohi

Pour 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)
    }


  }
0
Pankaj Jangid

Swift 4

À partir d'iOS 9, il est possible d'effacer le stockage persistant . Pour une meilleure maintenance, créez NSPersistentStoreCoordinator extension avec abstract function.

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
    }
}

Alors détruire le stockage persistant de SQLite semble assez simple:

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

Recommandations

  1. Mettez à jour destroyPersistentStore function qui est non nullable et génère des erreurs spécifiques, par exemple CoreDataError enum.
  2. Vous voulez probablement actualiser votre stockage persistant. Pour cela, vous pouvez utiliser addPersistentStore function of NSPersistentStoreCoordinator, avec l’objet extrait NSPersistentStore de destroyPersistentStore .
0
dimpiax

Swift 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)")
    }
}
0
Chris Chute