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.
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
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")
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) }
}
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)
}
}
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!
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")
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")
}
}
Il y a deux méthodes simples pour autant que je sache, d'abord
Méthode 1:
// 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:
// 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
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")
}
}
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);
}
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)
}
}
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.
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")
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) }
}
}
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) }
}
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)
}
}
À 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)
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)")
}
}