Datos principales: la forma más rápida de eliminar todas las instancias de una entidad

383

Estoy usando Core Data para persistir localmente los resultados de una llamada de servicios web. El servicio web devuelve el modelo de objeto completo para, digamos, "Autos", podría ser aproximadamente 2000 de ellos (y no puedo hacer que el Servicio Web devuelva nada menos que 1 o TODOS los autos.

La próxima vez que abra mi aplicación, quiero actualizar la copia persistente de Core Data llamando al Servicio Web para todos los Autos nuevamente, sin embargo, para evitar duplicados, primero necesitaría purgar todos los datos en la caché local.

¿Existe una forma más rápida de purgar TODAS las instancias de una entidad específica en el contexto del objeto administrado (por ejemplo, todas las entidades de tipo "CAR"), o necesito consultarlas para llamar, luego recorrer los resultados para eliminar cada una y luego guardar?

Idealmente, podría decir que elimine todo donde entidad es Blah.

Adaromas
fuente
Podría usar una base de datos en memoria
J. Doe

Respuestas:

718

iOS 9 y posterior:

iOS 9 agregó una nueva clase llamada NSBatchDeleteRequestque le permite eliminar fácilmente objetos que coinciden con un predicado sin tener que cargarlos todos en la memoria. Así es como lo usarías:

Swift 5

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

do {
    try myPersistentStoreCoordinator.execute(deleteRequest, with: myContext)
} catch let error as NSError {
    // TODO: handle the error
}

C objetivo

NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Car"];
NSBatchDeleteRequest *delete = [[NSBatchDeleteRequest alloc] initWithFetchRequest:request];

NSError *deleteError = nil;
[myPersistentStoreCoordinator executeRequest:delete withContext:myContext error:&deleteError];

Se puede encontrar más información sobre las eliminaciones por lotes en la sesión "Novedades de los datos básicos" de WWDC 2015 (a partir de las ~ 14:10).

iOS 8 y versiones anteriores:

Obtenerlos todos y eliminarlos todos:

NSFetchRequest *allCars = [[NSFetchRequest alloc] init];
[allCars setEntity:[NSEntityDescription entityForName:@"Car" inManagedObjectContext:myContext]];
[allCars setIncludesPropertyValues:NO]; //only fetch the managedObjectID

NSError *error = nil;
NSArray *cars = [myContext executeFetchRequest:allCars error:&error];
[allCars release];
//error handling goes here
for (NSManagedObject *car in cars) {
  [myContext deleteObject:car];
}
NSError *saveError = nil;
[myContext save:&saveError];
//more error handling here
Dave DeLong
fuente
74
También configuraría la búsqueda para recuperar solo el NSManagedObjectID para reducir cualquier sobrecarga de la carga en la estructura completa del objeto.
Marcus S. Zarra
38
No es obvio cómo obtener el NSMangagedObjectID .. use [allCars setIncludesPropertyValues: NO]; (¡y no se moleste en buscar cómo hacer una NSPropertyDescription para el ID de objeto!)
ohhorob
66
perdón por la pregunta de novato: ¿necesita guardar el contexto después del final del ciclo for? por ejemplo, [myContext save];
Steve
66
¿Alguna nueva instalación en Core Data para hacer esto más eficiente? Este es un problema grave para mi aplicación que ya se encuentra en el camino de la transferencia de datos a Core Data. Está tomando varios segundos eliminar las 4000 entradas de solo una de varias tablas. Esto es demasiado largo para que el usuario espere. La misma solicitud directamente con sqlite parece instantánea.
David
44
@DaveDeLong ¿Cómo NSBatchDeleteRequest puede activar el delegado NSFetchedResultsController? Intento casi todo, pero no pasa nada.
Foriger
36

Restablecer entidad en Swift 3 :

func resetAllRecords(in entity : String) // entity = Your_Entity_Name
    {

        let context = ( UIApplication.shared.delegate as! AppDelegate ).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")
        }
    }
Roy
fuente
32

Un poco más limpio y universal: agregue este método:

- (void)deleteAllEntities:(NSString *)nameEntity
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:nameEntity];
    [fetchRequest setIncludesPropertyValues:NO]; //only fetch the managedObjectID

    NSError *error;
    NSArray *fetchedObjects = [theContext executeFetchRequest:fetchRequest error:&error];
    for (NSManagedObject *object in fetchedObjects)
    {
        [theContext deleteObject:object];
    }

    error = nil;
    [theContext save:&error];
}
Jon - LBAB
fuente
16

Para Swift 2.0:

class func clearCoreData(entity:String) {
  let fetchRequest = NSFetchRequest()
  fetchRequest.entity = NSEntityDescription.entityForName(entity, inManagedObjectContext: moc!)
  fetchRequest.includesPropertyValues = false
  do {
    if let results = try moc!.executeFetchRequest(fetchRequest) as? [NSManagedObject] {
      for result in results {
        moc!.deleteObject(result)
      }

      try moc!.save()
    }
  } catch {
    LOG.debug("failed to clear core data")
  }
}
Gaurav Sharma
fuente
12

Rápido:

let fetchRequest = NSFetchRequest()
fetchRequest.entity = NSEntityDescription.entityForName(entityName, inManagedObjectContext: context)
fetchRequest.includesPropertyValues = false

var error:NSError?
if let results = context.executeFetchRequest(fetchRequest, error: &error) as? [NSManagedObject] {
    for result in results {
        context.deleteObject(result)
    }

    var error:NSError?
    if context.save(&error) {
        // do something after save

    } else if let error = error {
        println(error.userInfo)
    }

} else if let error = error {
    println("error: \(error)")
}
Ixx
fuente
1
Esta respuesta debe actualizarse con el nuevo manejo de errores de prueba / captura
Suragch
10

Esta es una pregunta similar a la de aquí y alguien sugirió configurar una regla de eliminación de relación para que solo tenga que eliminar un objeto. Por lo tanto, si tiene o puede crear una entidad con una relación de muchos a los automóviles y establece la regla de eliminación en cascada cuando elimina la entidad superior, todos los automóviles también se eliminarán. Esto puede ahorrar algo de tiempo de procesamiento ya que no tiene que seguir los pasos necesarios para cargar TODOS los automóviles. En un conjunto de datos más grande, esto podría ser absolutamente necesario.

T. Markle
fuente
1
Acabo de probar esto en mi proyecto actual con aproximadamente 600 objetos de datos principales. Cuando los encapsulé en otro objeto con cascada, tardé unos 9.1 segundos en eliminarlos. Si utilicé el método sugerido por Dave al respecto, la eliminación demora aproximadamente 8.7 segundos. No es una diferencia notable para mí.
Andrew Zimmer
8

Ya se publicó una buena respuesta, ¡esto es solo una recomendación!

Una buena manera sería simplemente agregar una categoría NSManagedObjecte implementar un método como lo hice:

Archivo de encabezado (por ejemplo NSManagedObject+Ext.h)

@interface NSManagedObject (Logic)

+ (void) deleteAllFromEntity:(NSString*) entityName;

@end

Archivo de código: (por ejemplo, NSManagedObject + Ext.m)

@implementation NSManagedObject (Logic)

+ (void) deleteAllFromEntity:(NSString *)entityName {
    NSManagedObjectContext *managedObjectContext = [AppDelegate managedObjectContext];
    NSFetchRequest * allRecords = [[NSFetchRequest alloc] init];
    [allRecords setEntity:[NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContext]];
    [allRecords setIncludesPropertyValues:NO];
    NSError * error = nil;
    NSArray * result = [managedObjectContext executeFetchRequest:allRecords error:&error];
    for (NSManagedObject * profile in result) {
        [managedObjectContext deleteObject:profile];
    }
    NSError *saveError = nil;
    [managedObjectContext save:&saveError];
}

@end

... lo único que tiene que hacer es obtener el ManageObjectContext del delegado de la aplicación, o de dónde lo tenga;)

luego puedes usarlo como:

[NSManagedObject deleteAllFromEntity:@"EntityName"];

Una optimización adicional podría ser que elimine el parámetro para el nombre de entidad y obtenga el nombre del nombre de clazz. esto llevaría al uso:

[ClazzName deleteAllFromEntity];

una impl más limpia (como categoría para NSManagedObjectContext):

@implementation NSManagedObjectContext (Logic)

- (void) deleteAllFromEntity:(NSString *)entityName {
    NSFetchRequest * allRecords = [[NSFetchRequest alloc] init];
    [allRecords setEntity:[NSEntityDescription entityForName:entityName inManagedObjectContext:self]];
    [allRecords setIncludesPropertyValues:NO];
    NSError * error = nil;
    NSArray * result = [self executeFetchRequest:allRecords error:&error];
    for (NSManagedObject * profile in result) {
        [self deleteObject:profile];
    }
    NSError *saveError = nil;
    [self save:&saveError];
}

@end

El uso entonces:

[managedObjectContext deleteAllFromEntity:@"EntityName"];
Erhard Dinhobl
fuente
1
Lo sentimos, pero [AppDelegate managedObjectContext]no es necesariamente una "arquitectura limpia" .. ;-)
Daniel Rinser
Ok cierto. Su código anterior se basa en un managedObjectContext. el primario;) En el código multiproceso, normalmente fusiono el MOC principal del delegado de la aplicación con los demás
Erhard Dinhobl el
1
@DanielRinser puede serdeleteAllFromEntity: inManagedObjectContext:
Mohamed Elkassas
Si. Mejor sería cambiar el método deleteAllFromEntity de un método de clase a un método de objeto. entonces puede llamar a deleteAllFromEntity directamente en una instancia de MOC.
Erhard Dinhobl
7

Actualización de Swift 4, iOS 12 y Xcode 10

100% trabajando solo cortar y pegar

Simplemente coloque esta función en la clase relevante y llame a esta función self.deleteData()en viewDidLoad()cualquier lugar o debajo de una función o un botón para que al hacer clic en un botón se eliminen todos los datos de la entidad y reemplace "myEntity" como su entidad que ha definido en su datos centrales

func deleteData() {
    let appDel:AppDelegate = (UIApplication.shared.delegate as! AppDelegate)
    let context:NSManagedObjectContext = appDel.persistentContainer.viewContext
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "myEntity")
    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 let error as NSError {
        print("Deleted all my data in myEntity error : \(error) \(error.userInfo)")
    }
}
Xcodian Solangi
fuente
Gracias, pero ¿por qué el concepto NSBatchDeleteRequest no funciona? alguna idea.
Suresh Durishetti
@SureshDurishetti, ¿ha importado CoreData en su clase?
Xcodian Solangi
1
Sí, agregó CoreDate. Pero sin suerte.
Suresh Durishetti
44
Olvidó agregar guardar llamada en el contexto, agregar context.save () y está listo para
comenzar
Sí, esto requiere guardar el contexto, de lo contrario no ocurrirá ningún cambio
Surendra Kumar
5

Swift 3.X y Swift 4.X , manera fácil. Cambiar solo YourTable

    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "YourTable")
    fetchRequest.returnsObjectsAsFaults = false

    do
    {
        let results = try context.fetch(fetchRequest)
        for managedObject in results
        {
            let managedObjectData:NSManagedObject = managedObject as! NSManagedObject
            context.delete(managedObjectData)
        }
    } catch let error as NSError {
        print("Detele all my data in \(entity) error : \(error) \(error.userInfo)")
    }
SwiftDeveloper
fuente
También puede usar esta construcción: let fetchRequest: NSFetchRequest <NSFetchRequestResult> = YourTable.fetchRequest ()
Daniil Chuiko
5

iOS 10 y posterior

Funciona con todas las versiones. Pase el nombre de la entidad e itere para eliminar todas las entradas y guardar el contexto.

func deleteData(entityToFetch: String, completion: @escaping(_ returned: Bool) ->()) {
        let context = NSManagedObjectContext()
        context = your managedObjectContext

        let fetchRequest = NSFetchRequest<NSFetchRequestResult>()
        fetchRequest.entity = NSEntityDescription.entity(forEntityName: entityToFetch, in: context)
        fetchRequest.includesPropertyValues = false
         do {   
            let results = try context.fetch(fetchRequest) as! [NSManagedObject]
            for result in results {
                context.delete(result)
            }
            try context.save()
            completion(true)
        } catch {
            completion(false)
            print("fetch error -\(error.localizedDescription)")
        }
    }
Karun Kumar
fuente
2
Gracias por publicar tu respuesta. Funciona para mi. Pero no deberías simplemente copiar y pegar tu código aquí. Para una newbee no está claro cuáles son sus CoreDataStack()o DataController()clases son. Se agradecería una actualización;)
Nico S.
4

Extendiendo la respuesta de Dave Delong.

Versión Swift que se encarga de iOS 9 y versiones anteriores también. También he cubierto el manejo de errores en esto:

let appDelegate: AppDelegate = UIApplication.sharedApplication (). delegar como! AppDelegate

    let fetchRequest = NSFetchRequest(entityName: "Car")
    if #available(iOS 9.0, *) {
        let delete = NSBatchDeleteRequest(fetchRequest: fetchRequest)
        do {
            try appDelegate.persistentStoreCoordinator.executeRequest(delete, withContext: appDelegate.managedObjectContext)
        } catch let error as NSError {
            print("Error occured while deleting: \(error)")
        }
    } else {
        // Fallback on earlier versions
        let carRequest = NSFetchRequest()
        carRequest.entity = NSEntityDescription.entityForName("Cars", inManagedObjectContext: appDelegate.managedObjectContext)
        carRequest.includesPropertyValues = false

        do {
            let cars: NSArray = try appDelegate.managedObjectContext.executeFetchRequest(carRequest)

            for car in cars {
                appDelegate.managedObjectContext.delete(car)
            }

            try appDelegate.managedObjectContext.save()

        } catch let error as NSError {
            print("Error occured while fetching or saving: \(error)")
        }
    }
Maheen Khalid
fuente
Votado iOS 9 forma de eliminar los registros es realmente impresionante.
Shobhakar Tiwari
2

¿Por qué no plegar los datos que recibe con el caché existente? De lo contrario, no es realmente "refrescante", es "comenzar de nuevo" y también podría soltar / eliminar el archivo SQLLite y comenzar de nuevo (suponiendo que no persista también otros datos).

AlBlue
fuente
1
Mala solución Si hay otras tablas en la base de datos Sqlite, obviamente perderemos todo eso. Esto es más un truco para una solución particular y no puede considerarse para los casos más grandes.
Deepak GM
2

Swift 4, iOS 10+
Función estática que se puede aplicar a cualquier entidad para eliminar todos sus datos

protocol NSManagedObjectHelper {
}
extension NSManagedObject: NSManagedObjectHelper {
}
extension NSManagedObjectHelper where Self: NSManagedObject {
    static func removeAllObjectsInContext(_ managedContext: NSManagedObjectContext) {
        let request: NSFetchRequest = NSFetchRequest(entityName: String(describing: self))
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: request)
        do {
            deleteRequest.resultType = .resultTypeObjectIDs//to clear objects from memory
            let result = try managedContext.execute(deleteRequest) as? NSBatchDeleteResult
            if let objectIDArray = result?.result as? [NSManagedObjectID] {
                let changes = [NSDeletedObjectsKey : objectIDArray]
                /*By calling mergeChangesFromRemoteContextSave, all of the NSManagedObjectContext instances that are referenced will be notified that the list of entities referenced with the NSManagedObjectID array have been deleted and that the objects in memory are stale. This causes the referenced NSManagedObjectContext instances to remove any objects in memory that are loaded which match the NSManagedObjectID instances in the array.*/
                NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [managedContext])
            }
            try managedContext.save()
        } catch let error {
            print(error)
        }
    }
}

'Habitación' es una entidad

Room.removeAllObjectsInContext(self.persistentContainer.viewContext)

Editado en 20191025: la instrucción "Self.fetchRequest ()" puede causar problemas si usamos múltiples objetivos en los mismos proyectos. Entonces reemplazado con NSFetchRequest (entityName: String (describing: self))

jpulikkottil
fuente
1

si la entidad contiene muchas entradas, la mejor manera es así porque ahorra memoria

 - (void)deleteAll:(NSManagedObjectContext *)managedObjectContext entityName:(NSString *)entityName
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [managedObjectContext setUndoManager:nil];
    NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];
    [fetchRequest setIncludesPropertyValues:NO];
    [fetchRequest setFetchLimit:100]; // you can change this number if you want
    NSError *error;
    NSArray *items = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
    while ([items count] > 0) {
        @autoreleasepool {
            for (NSManagedObject *item in items) {
                [managedObjectContext deleteObject:item];
            }
            if (![managedObjectContext save:&error]) {
                NSLog(@"Error deleting %@ - error:%@",self.entityName, error);
            }
        }
        items = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
    }
}
fiebre poyo
fuente
1

En 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")
        }
    }
Amul4608
fuente
1

Este código funcionará tanto para iOS 9 como para versiones inferiores.

class func deleteAllRecords(in entity : String) // entity = Your_Entity_Name
    {

        let context = CoreDataStack.getContext() // Note:- Replace your context here with CoreDataStack.getContext()
        let deleteFetch = NSFetchRequest<NSFetchRequestResult>(entityName: entity)
        if #available(iOS 9, *)
        {
            let deleteRequest = NSBatchDeleteRequest(fetchRequest: deleteFetch)
            do
            {
                try context.execute(deleteRequest)
                try context.save()
            }
            catch
            {
                print("There was an error:\(error)")
            }
        }
        else
        {
            do{
                let deleteRequest = try context.fetch(deleteFetch)
                for anItem in deleteRequest {
                    context.delete(anItem as! NSManagedObject)
                }
            }
            catch
            {
                print("There was an error:\(error)")
            }
        }
        CoreDataStack.saveContext() // Note:- Replace your savecontext here with CoreDataStack.saveContext()
    }
Varun Naharia
fuente
1

iOS 9.0 y posterior:

NSBatchDeleteRequestse utiliza para eliminar registros en datos centrales. Funciona muy rápido y toma menos tiempo eliminar todos los registros de una entidad. Se requiere NSFetchRequesten la discusión. Si desea eliminar todos los registros de una entidad, puede usarlo y funciona para mí.

let manageObject:NSManagedObjectContext = appDelegateObject.managedObjectContext

let fetchRequest = NSFetchRequest(entityName: EnityName”)

let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)

let persistCor:NSPersistentStoreCoordinator = appDelegateObject.persistentObject
 do {
        try persistCor.executeRequest(deleteRequest, withContext: manageObject)
        try manageObject.save()
    } catch {
        print(error?.localizedDescription)
    }
Desarrollador MARK IOS
fuente
1

purga rápida de todos los objetos en DB:

func purgeAllData() {
    let uniqueNames = persistentContainer.managedObjectModel.entities.compactMap({ $0.name })

    uniqueNames.forEach { (name) in
      let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: name)
       let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
         do {
        try persistentContainer.viewContext.execute(batchDeleteRequest)
      } catch {
        let nserror = error as NSError
        fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
      }
   }
 }
gbk
fuente
0

La respuesta de Dave Delongs Swift 2.0 me estaba fallando (en iOS 9)

Pero esto funcionó:

let fetchRequest = NSFetchRequest(entityName: "Car")
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)

    do {
        try managedObjectContext.executeRequest(deleteRequest)
        try managedObjectContext.save()
    }
    catch let error as NSError {
       // Handle error
    }
resplandor
fuente
0

Solución Swift 3 con iOS 9 'NSBatchDeleteRequest' y respaldo a versiones anteriores de iOS implementadas como una extensión en 'NSManagedObjectContext'. Referencia de Apple https://developer.apple.com/library/content/featuredarticles/CoreData_Batch_Guide/BatchDeletes/BatchDeletes.html

extension NSManagedObjectContext {
    func batchDeleteEntities<T: NSManagedObject>(ofType type: T.Type) throws {
        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: String(describing: type.self))
        if #available(iOS 9.0, *) {
            let request = NSBatchDeleteRequest(fetchRequest: fetchRequest)
            let result = try execute(request) as? NSBatchDeleteResult
            if let objectIDArray = result?.result as? [NSManagedObjectID] {
                let changes = [NSDeletedObjectsKey: objectIDArray]
                NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [self])
            }
        } else {
            fetchRequest.includesPropertyValues = false
            let results = try fetch(fetchRequest)
            if let actualResults = results as? [NSManagedObject], !actualResults.isEmpty {
                actualResults.forEach { delete($0) }
            }
        }
    }
}
chriswillow
fuente
0

Use NSBatchDeleteRequest para eliminar varios registros si el mínimo de iOS es 9.0. Si es un subproceso en segundo plano, ejecute NSManagedObjectContext save, de lo contrario, use NSFetchRequest para obtener registros y eliminar todos los registros en el bucle y Guardar una vez que se haya eliminado.

Jeetendra Kumar
fuente
0

en iOS 11.3 y Swift 4.1

let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
        let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest )
        batchDeleteRequest.resultType = .resultTypeCount
        do {
            let batchDeleteResult = try dataController.viewContext.execute(batchDeleteRequest) as! NSBatchDeleteResult
            print("The batch delete request has deleted \(batchDeleteResult.result!) records.")
            dataController.viewContext.reset() // reset managed object context (need it for working)
        } catch {
            let updateError = error as NSError
            print("\(updateError), \(updateError.userInfo)")
        }

tienes que llamar a reset después de ejecutar. De lo contrario, no se actualizará en la vista de tabla.

tien113
fuente
0
    func deleteAll(entityName: String) {

    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
    let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
    deleteRequest.resultType = .resultTypeObjectIDs
    guard let context = self.container?.viewContext
        else { print("error in deleteAll")
            return }

    do {
        let result = try context.execute(deleteRequest) as? NSBatchDeleteResult
        let objectIDArray = result?.result as? [NSManagedObjectID]
        let changes: [AnyHashable : Any] = [NSDeletedObjectsKey : objectIDArray as Any]
        NSManagedObjectContext.mergeChanges(fromRemoteContextSave: changes, into: [context])
    } catch {
        print(error.localizedDescription)
    }
}
Matt Bearson
fuente
0

la forma OOP sin cadenas como nombres de entidades Swift 3+, Xcode 10+

func batchDelete<T>(in context: NSManagedObjectContext, fetchRequest: NSFetchRequest<T>) throws {
    guard let request = fetchRequest as? NSFetchRequest<NSFetchRequestResult> else {
        throw ErrorService.defaultError
    }
    let batchDeleteRequest = NSBatchDeleteRequest(fetchRequest: request)
    do {
        try context.execute(batchDeleteRequest)
    } catch {
        throw error
    }
}

entonces solo llame al bloque do / catch

    let fetchRequest: NSFetchRequest<YourEntity> = YourEntity.fetchRequest()
    do {
        let data = try context.fetch(fetchRequest)
        if data.count > 0 {
            try self.batchDelete(in: context, fetchRequest: fetchRequest)
        }
    } catch {
        // throw error
    }
Jack Daniel
fuente
-1

En Swift 2.0:

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)")
    }
}
Rajesh Loganathan
fuente