Dados principais: maneira mais rápida de excluir todas as instâncias de uma entidade

383

Estou usando o Core Data para persistir localmente os resultados de uma chamada de Serviços da Web. O serviço da Web retorna o modelo de objeto completo para, digamos, "Carros" - pode ter cerca de 2000 deles (e não posso fazer com que o Serviço da Web retorne nada menos que 1 ou TODOS os carros.

Na próxima vez que abrir meu aplicativo, desejo atualizar a cópia persistente dos Dados Principais, ligando para o Serviço Web de todos os Carros novamente. No entanto, para evitar duplicatas, precisaria limpar todos os dados no cache local primeiro.

Existe uma maneira mais rápida de limpar TODAS as instâncias de uma entidade específica no contexto do objeto gerenciado (por exemplo, todas as entidades do tipo "CAR"), ou eu preciso consultá-las, em seguida, percorrer os resultados para excluir cada um e salvar?

Idealmente, eu poderia dizer excluir tudo onde entidade é Blah.

Adaromas
fonte
Você poderia usar um banco de dados na memória
J. Doe

Respostas:

718

iOS 9 e posterior:

O iOS 9 adicionou uma nova classe chamada NSBatchDeleteRequestque permite excluir facilmente objetos correspondentes a um predicado sem precisar carregá-los todos na memória. Veja como você o usaria:

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
}

Objetivo-C

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

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

Mais informações sobre exclusões em lote podem ser encontradas na sessão "O que há de novo nos dados principais" da WWDC 2015 (a partir das ~ 14: 10).

iOS 8 e versões anteriores:

Busque todos eles e exclua 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
fonte
74
Eu também configuraria a busca para recuperar apenas o NSManagedObjectID para reduzir qualquer sobrecarga do carregamento na estrutura completa do objeto.
Marcus S. Zarra
38
Não é óbvio como buscar apenas o NSMangagedObjectID .. use [allCars setIncludesPropertyValues: NO]; (e não se incomodam de caça em torno de como fazer um NSPropertyDescription para a identificação do objeto!)
ohhorob
6
desculpe pela pergunta do novato: você precisa salvar o contexto após o final do loop for? por exemplo [salvar myContext];
Steve
6
Alguma nova instalação no Core Data para tornar isso mais eficiente? Esse é um problema sério para o meu aplicativo que já está no caminho de portar dados principais. Está levando vários segundos para excluir todas as 4000 entradas de apenas uma das várias tabelas. Isso é muito longo para o usuário aguardar. O mesmo pedido diretamente com o sqlite parece instantâneo.
David
4
@DaveDeLong Como o NSBatchDeleteRequest pode acionar o delegado NSFetchedResultsController? Eu tento quase tudo, mas nada acontece.
Foriger 30/07/2015
36

Redefinir entidade no 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
fonte
32

Um pouco mais limpo e universal: adicione 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
fonte
16

Para o 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
fonte
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
fonte
11
Essa resposta deve ser atualizado com o novo tratamento de erros try / catch
Suragch
10

Essa é uma pergunta semelhante à pergunta aqui e alguém sugeriu a configuração de uma regra de exclusão de relacionamento, portanto, você só precisa excluir um objeto. Portanto, se você tiver ou puder criar uma entidade com um relacionamento de muitos com os carros e definir a regra de exclusão para cascata ao excluir a entidade superior, todos os carros também serão excluídos. Isso pode economizar tempo de processamento, pois você não precisa executar as etapas envolvidas no carregamento de TODOS os carros. Em um conjunto de dados maior, isso pode ser absolutamente necessário.

T. Markle
fonte
11
Eu apenas tentei isso no meu projeto atual com cerca de 600 objetos de dados principais. Quando eu os encapsulei em outro objeto com cascata, demorou cerca de 9,1 segundos para excluir. Se eu usei o método sugerido por Dave, leva cerca de 8,7 segundos para excluir. Não é uma diferença notável para mim.
Andrew Zimmer
8

Uma boa resposta já foi postada, isso é apenas uma recomendação!

Uma boa maneira seria apenas adicionar uma categoria NSManagedObjecte implementar um método como eu fiz:

Arquivo de cabeçalho (por exemplo NSManagedObject+Ext.h)

@interface NSManagedObject (Logic)

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

@end

Arquivo de código: (por exemplo, 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

... a única coisa que você precisa fazer é obter o managedObjectContext do delegado do aplicativo ou de onde você estiver;)

depois você pode usá-lo como:

[NSManagedObject deleteAllFromEntity:@"EntityName"];

outra otimização poderia ser a remoção do parâmetro para o nome da entidade e o nome do nome do clazz. isso levaria ao uso:

[ClazzName deleteAllFromEntity];

um impl mais limpo (como categoria 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

O uso então:

[managedObjectContext deleteAllFromEntity:@"EntityName"];
Erhard Dinhobl
fonte
11
Desculpe, mas [AppDelegate managedObjectContext]não é necessariamente uma "arquitetura limpa" .. ;-)
Daniel Rinser
Ok verdade. Seu código acima é baseado em um managedObjectContext. a primária;) No código multithreaded i normalmente mesclar a principal MOC do delegado aplicativo para os outros
Erhard Dinhobl
11
@DanielRinser can bedeleteAllFromEntity: inManagedObjectContext:
Mohamed Elkassas
Sim. Melhor seria alterar o método deleteAllFromEntity de um método de classe para um método de objeto. então você pode chamar o deleteAllFromEntity diretamente em uma instância do MOC.
precisa saber é o seguinte
7

Atualização Swift 4, iOS 12 e Xcode 10

100% trabalhando apenas recortar e colar

Basta colocar essa função na classe relevante e chamar essa função self.deleteData()em viewDidLoad()ou em qualquer lugar ou abaixo de uma função ou botão para que, ao clicar em um botão, todos os dados da entidade sejam excluídos e substitua "myEntity" como sua entidade que você definiu em sua entidade. dados principais

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
fonte
Obrigado, mas por que o conceito NSBatchDeleteRequest não está funcionando? qualquer ideia.
Suresh Durishetti 17/01/2019
@SureshDurishetti você importou CoreData em sua classe?
Xcodian Solangi
11
Sim, adicionou CoreDate. Mas sem sorte.
Suresh Durishetti
4
Você esqueceu de acrescentar chamada save do contexto, adicione context.save () e você está pronto para ir
Parama Dharmika
Sim, isso requer para salvar contexto de outra forma nenhuma mudança vai acontecer
Surendra Kumar
5

Swift 3.X e Swift 4.X , Maneira fácil. Alterar apenas 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
fonte
Também você pode usar esta construção: vamos fetchRequest: NSFetchRequest <NSFetchRequestResult> = YourTable.fetchRequest ()
Daniil Chuiko
5

iOS 10 e posterior

Funciona com todas as versões. Passe o nome da entidade e percorra para excluir todas as entradas e salvar o 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
fonte
2
Obrigado por postar sua resposta. Isso funciona para mim. Mas você não deve apenas copiar e colar seu código aqui. Para uma newbee não está claro o que seus CoreDataStack()ou DataController()classes são. Uma atualização seria apreciada;)
Nico S.
4

Estendendo a resposta de Dave Delong.

Versão Swift que cuida do iOS 9 e versões anteriores também. Também abordamos o tratamento de erros:

deixe 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
fonte
votado. iOS 9 maneira de excluir os registros é realmente awsm.
Shobhakar Tiwari 31/03
2

Por que não dobrar os dados que você recebe com o cache existente? Caso contrário, não é realmente 'refrescante', está 'começando de novo' e você também pode excluir / excluir o arquivo SQLLite e começar de novo (supondo que você não persista outros dados também).

AlBlue
fonte
11
Solução ruim. Se houver outras tabelas no banco de dados Sqlite, obviamente perderemos tudo isso. Isso é mais um truque para uma solução específica e não pode ser considerado para os casos maiores.
Deepak GM
2


Função estática Swift 4, iOS 10+ , que pode ser aplicada a qualquer entidade para remover todos os seus dados

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

'Room' é uma entidade

Room.removeAllObjectsInContext(self.persistentContainer.viewContext)

Editada em 20191025: a instrução "Self.fetchRequest ()" pode causar problemas se usarmos vários destinos nos mesmos projetos. Substituído por NSFetchRequest (entityName: String (descrevendo: self))

jpulikkottil
fonte
1

se a entidade contiver muitas entradas, a melhor maneira é a seguinte, pois economiza memória

 - (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];
    }
}
febre do poyo.
fonte
1

No 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
fonte
1

Este código funcionará para iOS 9 e abaixo

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
fonte
1

iOS 9.0 e posterior:

NSBatchDeleteRequesté usado para excluir registros nos dados principais. Funciona muito rápido e leva menos tempo para excluir todos os registros de uma entidade. Requer NSFetchRequestno argumento. Se você deseja excluir todos os registros de uma entidade, pode usá-lo e funciona para mim.

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)
    }
MARK IOS Developer
fonte
1

limpeza rápida de todos os objetos no 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
fonte
0

A resposta Swift 2.0 de Dave Delongs estava falhando para mim (no iOS 9)

Mas isso funcionou:

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
    }
brilho
fonte
0

Solução Swift 3 com o iOS 9 'NSBatchDeleteRequest' e fallback para versões anteriores do iOS implementadas como uma extensão no 'NSManagedObjectContext'. Referência da 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
fonte
0

Use NSBatchDeleteRequest para excluir vários registros Se o iOS mínimo for 9.0. Se o encadeamento em segundo plano, executar o NSManagedObjectContext, salve mais, use NSFetchRequest para obter registros e excluir todos os registros no loop for e Salvar quando a exclusão for concluída.

Jeetendra Kumar
fonte
0

no iOS 11.3 e 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)")
        }

você precisa chamar reset depois de executar. Caso contrário, ele não será atualizado na exibição da tabela.

tien113
fonte
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
fonte
0

da maneira OOP sem nenhuma string, como o nome das 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
    }
}

então basta ligar no bloco 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
fonte
-1

No 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
fonte