Удалить/сбросить все записи в основных данных?
-
21-08-2019 - |
Вопрос
Знаете ли вы какой-нибудь способ удалить все записи, хранящиеся в Core Data?Моя схема должна остаться прежней;Я просто хочу сбросить его до пустого состояния.
Редактировать
Я хочу сделать это программно, чтобы пользователь мог по существу нажать reset
кнопка.
Решение
Вы по-прежнему можете удалить файл программно, используя NSFileManager:removeItemAtPath::метод.
NSPersistentStore *store = ...;
NSError *error;
NSURL *storeURL = store.URL;
NSPersistentStoreCoordinator *storeCoordinator = ...;
[storeCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];
Затем просто добавьте постоянное хранилище обратно, чтобы убедиться, что оно воссоздано правильно.
Программный способ перебора каждого объекта медленнее и подвержен ошибкам.Это можно использовать, если вы хотите удалить некоторые объекты, а не другие.Однако вам все равно необходимо убедиться, что вы сохраняете ссылочную целостность, иначе вы не сможете сохранить свои изменения.
Простое удаление хранилища и его воссоздание — это быстро и безопасно, и, безусловно, это можно сделать программно во время выполнения.
Обновление для iOS5+
С появлением внешнего двоичного хранилища (позволяетExternalBinaryDataStorage или Store in external Record File) в iOS 5 и OS X 10.7 простого удаления файлов, на которые указывают StoreURL, недостаточно.Вы оставите внешние файлы записей.Поскольку схема именования этих внешних файлов записей не является общедоступной, у меня пока нет универсального решения.— an0 08 май 2012, в 23:00
Другие советы
Вы можете удалить файл SQLite, но я решил сделать это, очистив таблицы по отдельности с помощью функций:
- (void) deleteAllObjects: (NSString *) entityDescription {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityDescription inManagedObjectContext:_managedObjectContext];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *items = [_managedObjectContext executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];
for (NSManagedObject *managedObject in items) {
[_managedObjectContext deleteObject:managedObject];
DLog(@"%@ object deleted",entityDescription);
}
if (![_managedObjectContext save:&error]) {
DLog(@"Error deleting %@ - error:%@",entityDescription,error);
}
}
Причина, по которой я решил делать это таблица за таблицей, заключается в том, что это заставляет меня во время программирования убедиться, что удаление содержимого таблицы разумно и нет данных, которые я бы предпочел сохранить.
Это будет намного медленнее, чем просто удаление файла, и я перейду на удаление файла, если этот метод займет слишком много времени.
Обновленное решение для iOS 10+
Использовать NSBatchDeleteRequest
удалить все объекты в сущности без необходимости загружать их в память или перебирать их.
// create the delete request for the specified entity
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = MyEntity.fetchRequest()
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
// get reference to the persistent container
let persistentContainer = (UIApplication.shared.delegate as! AppDelegate).persistentContainer
// perform the delete
do {
try persistentContainer.viewContext.execute(deleteRequest)
} catch let error as NSError {
print(error)
}
Этот код был обновлен для iOS 10 и Swift 3.Если вам нужна поддержка iOS 9, см. этот вопрос.
Источники:
- Основные данные:Самый быстрый способ удалить все экземпляры объекта (включая код Objective-C)
- Что нового в основных данных (видео WWDC 2015)
- Что нового в основных данных (Видео WWDC 2016)
- Как использовать основные данные в iOS 10
- Что нового в Core Data Swift 3.0
Я написал clearStores
метод, который проходит через каждое хранилище и удаляет его как из координатора, так и из файловой системы (обработка ошибок оставлена в стороне):
NSArray *stores = [persistentStoreCoordinator persistentStores];
for(NSPersistentStore *store in stores) {
[persistentStoreCoordinator removePersistentStore:store error:nil];
[[NSFileManager defaultManager] removeItemAtPath:store.URL.path error:nil];
}
[persistentStoreCoordinator release], persistentStoreCoordinator = nil;
Этот метод находится внутри coreDataHelper
класс, который заботится (помимо прочего) о создании постоянного хранилища, когда оно равно нулю.
Я удаляю все данные из основных данных в событии кнопки в классе HomeViewController:Эта статья мне настолько помогла, что я решил внести свой вклад.
-(IBAction)buttonReset:(id)sender
{
NSLog(@"buttonReset Pressed");
//Erase the persistent store from coordinator and also file manager.
NSPersistentStore *store = [self.persistentStoreCoordinator.persistentStores lastObject];
NSError *error = nil;
NSURL *storeURL = store.URL;
[self.persistentStoreCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error];
NSLog(@"Data Reset");
//Make new persistent store for future saves (Taken From Above Answer)
if (![self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// do something with the error
}
}
Обратите внимание, что для вызова self.persistentStoreCoordinator я объявил свойство в контроллере домашнего представления.(Не беспокойтесь о управляемом объектномконтексте, который я использую для сохранения и загрузки.)
@property (nonatomic, retain) NSManagedObjectContext * managedObjectContext;
@property (nonatomic, retain) NSPersistentStoreCoordinator * persistentStoreCoordinator;
Затем в AppDelegate ApplicationDidFinishLaunching прямо под созданием HomeViewController у меня есть:
homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil];
homeViewController.managedObjectContext = self.managedObjectContext;
homeViewController.persistentStoreCoordinator = self.persistentStoreCoordinator;
Волшебная запись делает это очень легко.
[MyCoreDataObject MR_truncateAll];
iOS9+, Свифт 2
Удалить все объекты во всех сущностях
func clearCoreDataStore() {
let entities = managedObjectModel.entities
for entity in entities {
let fetchRequest = NSFetchRequest(entityName: entity.name!)
let deleteReqest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
do {
try context.executeRequest(deleteReqest)
} catch {
print(error)
}
}
}
[Поздний ответ в ответ на награду за новые ответы]
Просматривая предыдущие ответы,
- Получение и удаление всех элементов, предложенное @Grouchal и другими, по-прежнему является эффективным и полезным решением.Если у вас очень большие хранилища данных, это может быть медленно, но все равно работает очень хорошо.
- Простое удаление хранилища данных, как вы и @groundhog заметили, уже неэффективно.Это устарело даже если вы не используете внешнее двоичное хранилище потому что iOS 7 использует режим WAL для ведения журнала SQLite.В режиме WAL в любом постоянном хранилище Core Data могут храниться (потенциально большие) файлы журнала.
Но есть другой, похожий подход к удалению постоянного хранилища, который действительно работает.Главное — поместить файл постоянного хранилища в отдельный подкаталог, который больше ничего не содержит.Не просто вставляйте его в каталог документов (или где-то еще), создайте новый подкаталог только для постоянного хранилища.Содержимым этого каталога в конечном итоге будут файл постоянного хранилища, файлы журнала и внешние двоичные файлы.Если вы хотите уничтожить все хранилище данных, удалите этот каталог, и все они исчезнут.
При настройке постоянного хранилища вы должны сделать что-то подобное:
NSURL *storeDirectoryURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"persistent-store"];
if ([[NSFileManager defaultManager] createDirectoryAtURL:storeDirectoryURL
withIntermediateDirectories:NO
attributes:nil
error:nil]) {
NSURL *storeURL = [storeDirectoryURL URLByAppendingPathComponent:@"MyApp.sqlite"];
// continue with storeURL as usual...
}
Затем, когда вы захотели удалить магазин,
[[NSFileManager defaultManager] removeItemAtURL:storeDirectoryURL error:nil];
Это рекурсивно удаляет как пользовательский подкаталог, так и все файлы Core Data в нем.
Это работает только в том случае, если у вас еще нет постоянного хранилища в той же папке, что и другие важные данные..Например, каталог документов, в котором, вероятно, есть и другие полезные вещи.Если это ваша ситуация, вы можете получить тот же эффект, ища файлы, которые вы делать хочу сохранить и удалить все остальное.Что-то вроде:
NSString *docsDirectoryPath = [[self applicationDocumentsDirectory] path];
NSArray *docsDirectoryContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:docsDirectoryPath error:nil];
for (NSString *docsDirectoryItem in docsDirectoryContents) {
// Look at docsDirectoryItem. If it's something you want to keep, do nothing.
// If it's something you don't recognize, remove it.
}
Этот подход может быть подвержен ошибкам.Вы должны быть абсолютно уверены, что знаете каждый файл, который вы хотите сохранить, поскольку в противном случае вы можете удалить важные данные.С другой стороны, вы можете удалить внешние двоичные файлы, фактически не зная имени файла/каталога, используемого для их хранения.
Если вы хотите удалить все объекты и не хотите удалять файлы поддержки, вы можете использовать следующие методы:
- (void)deleteAllObjectsInContext:(NSManagedObjectContext *)context
usingModel:(NSManagedObjectModel *)model
{
NSArray *entities = model.entities;
for (NSEntityDescription *entityDescription in entities) {
[self deleteAllObjectsWithEntityName:entityDescription.name
inContext:context];
}
}
- (void)deleteAllObjectsWithEntityName:(NSString *)entityName
inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *fetchRequest =
[NSFetchRequest fetchRequestWithEntityName:entityName];
fetchRequest.includesPropertyValues = NO;
fetchRequest.includesSubentities = NO;
NSError *error;
NSArray *items = [context executeFetchRequest:fetchRequest error:&error];
for (NSManagedObject *managedObject in items) {
[context deleteObject:managedObject];
NSLog(@"Deleted %@", entityName);
}
}
Имейте в виду, что это может быть очень медленно (зависит от количества объектов в вашем графе объектов).
Вот комбинированное решение для очистки основных данных.
- (void)deleteAllObjectsInCoreData
{
NSArray *allEntities = self.managedObjectModel.entities;
for (NSEntityDescription *entityDescription in allEntities)
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entityDescription];
fetchRequest.includesPropertyValues = NO;
fetchRequest.includesSubentities = NO;
NSError *error;
NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (error) {
NSLog(@"Error requesting items from Core Data: %@", [error localizedDescription]);
}
for (NSManagedObject *managedObject in items) {
[self.managedObjectContext deleteObject:managedObject];
}
if (![self.managedObjectContext save:&error]) {
NSLog(@"Error deleting %@ - error:%@", entityDescription, [error localizedDescription]);
}
}
}
Если вы хотите пойти по пути удаления всех объектов (который намного проще, чем удаление стека Core Data, но менее производительен), то это лучшая реализация:
- (void)deleteAllManagedObjectsInModel:(NSManagedObjectModel *)managedObjectModel context:(NSManagedObjectContext *)managedObjectContext
{
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
[managedObjectContext performBlockAndWait:^{
for (NSEntityDescription *entity in managedObjectModel) {
NSFetchRequest *fetchRequest = [NSFetchRequest new];
[fetchRequest setEntity:entity];
[fetchRequest setIncludesSubentities:NO];
NSArray *objects = [managedObjectContext executeFetchRequest:fetchRequest error:nil];
for (NSManagedObject *managedObject in objects) {
[managedObjectContext deleteObject:managedObject];
}
}
[managedObjectContext save:nil];
}];
}];
[operation setCompletionBlock:^{
// Do stuff once the truncation is complete
}];
[operation start];
}
Эта реализация использует NSOperation
выполнить удаление основного потока и уведомить о завершении.Возможно, вы захотите отправить уведомление или что-то в блоке завершения, чтобы вернуть статус обратно в основной поток.
Решение iOS 10 + Swift 3:
func clearCoreDataStore() {
let delegate = UIApplication.shared.delegate as! AppDelegate
let context = delegate.persistentContainer.viewContext
for i in 0...delegate.persistentContainer.managedObjectModel.entities.count-1 {
let entity = delegate.persistentContainer.managedObjectModel.entities[i]
do {
let query = NSFetchRequest<NSFetchRequestResult>(entityName: entity.name!)
let deleterequest = NSBatchDeleteRequest(fetchRequest: query)
try context.execute(deleterequest)
try context.save()
} catch let error as NSError {
print("Error: \(error.localizedDescription)")
abort()
}
}
}
Перебирает все основные объекты данных и очищает их.
Вот несколько упрощенная версия с меньшим количеством вызовов AppDelegate self и последним фрагментом кода, который не попал в ответ с самым высоким рейтингом.Также я получал сообщение об ошибке «Постоянное хранилище объекта недоступно из координатора этого NSManagedObjectContext», поэтому просто нужно было добавить его обратно.
NSPersistentStoreCoordinator *storeCoordinator = [self persistentStoreCoordinator];
NSPersistentStore *store = [[storeCoordinator persistentStores] lastObject];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"dataModel"];
NSError *error;
[storeCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];
[_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error];
if (storeCoordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:storeCoordinator];
}
быстрое решение:
class func deleteAllManagedObjects() {
let modelURL = NSBundle.mainBundle().URLForResource("some string", withExtension: "mom")
let mom = NSManagedObjectModel(contentsOfURL: modelURL)
for entityName in mom.entitiesByName.keys {
let fr = NSFetchRequest(entityName: entityName as String)
let a = Utility.managedObjectContext().executeFetchRequest(fr, error: nil) as [NSManagedObject]
for mo in a {
Utility.managedObjectContext().deleteObject(mo)
}
}
Utility.managedObjectContext().save(nil)
}
В качестве краткой справки для сохранения поиска в другом месте — воссоздание постоянного хранилища после его удаления можно выполнить с помощью:
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// do something with the error
}
Спасибо за пост.Я последовал этому, и это сработало для меня.Но у меня была еще одна проблема, о которой не упоминалось ни в одном из ответов.Так что я не уверен, что это был только я.
В любом случае, я решил опубликовать здесь проблему и способ ее решения.
У меня было несколько записей в базе данных, я хотел очистить все, прежде чем записывать новые данные в базу данных, поэтому я сделал все, включая
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error];
а затем использовал managedObjectContext
чтобы получить доступ к базе данных (которая уже должна была быть пустой), каким-то образом данные все еще были там.После некоторого времени устранения неполадок я обнаружил, что мне нужно выполнить сброс managedObjectContext
, managedObject
, managedObjectModel
иpersistentStoreCoordinator
, прежде чем использовать managedObjectContext
для доступа к базе данных.Теперь у меня есть чистая база данных для записи.
Несколько хороших ответов на этот вопрос.Вот хороший лаконичный вариант.Первые две строки удаляют базу данных sqlite.Тогда для:цикл удаляет любые объекты в памяти ManagedObjectContext.
NSURL *storeURL = [[(FXYAppDelegate*)[[UIApplication sharedApplication] delegate] applicationDocumentsDirectory] URLByAppendingPathComponent:@"AppName.sqlite"];
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil];
for (NSManagedObject *ct in [self.managedObjectContext registeredObjects]) {
[self.managedObjectContext deleteObject:ct];
}
вы также можете найти все имена объектов и удалить их по имени.Это более длинная версия, но работает хорошо, поэтому вам не придется работать с постоянным хранилищем.
- (void)clearCoreData
{
NSError *error;
NSEntityDescription *des = [NSEntityDescription entityForName:@"Any_Entity_Name" inManagedObjectContext:_managedObjectContext];
NSManagedObjectModel *model = [des managedObjectModel];
NSArray *entityNames = [[model entities] valueForKey:@"name"];
for (NSString *entityName in entityNames){
NSFetchRequest *deleteAll = [NSFetchRequest fetchRequestWithEntityName:entityName];
NSArray *matches = [self.database.managedObjectContext executeFetchRequest:deleteAll error:&error];
}
if (matches.count > 0){
for (id obj in matches){
[_managedObjectContext deleteObject:obj];
}
[self.database.managedObjectContext save:&error];
}
}
для «Any_Entity_Name» просто укажите любое имя вашей сущности, нам нужно только выяснить описание сущности, в которой находятся ваши сущности.ValueForKey@"name" вернет все имена объектов.Наконец, не забудьте сохраниться.
Принятый ответ верен, удаление URL-адреса с помощью NSFileManager является правильным, но, как указано в редактировании iOS 5+, постоянное хранилище не представлено только одним файлом.Для хранилища SQLite это *.sqlite, *.sqlite-shm и *.sqlite-wal...к счастью, начиная с iOS 7+, мы можем использовать метод
NspersistentStoreCoordinator +removeBiquiquiquitSontentAndPersistentStoreAtUrl: Параметры: Ошибка:
чтобы позаботиться об удалении, поэтому код должен быть примерно таким:
NSPersistentStore *store = ...;
NSError *error;
NSURL *storeURL = store.URL;
NSString *storeName = ...;
NSPersistentStoreCoordinator *storeCoordinator = ...;
[storeCoordinator removePersistentStore:store error:&error];
[NSPersistentStoreCoordinator removeUbiquitousContentAndPersistentStoreAtURL:storeURL.path options:@{NSPersistentStoreUbiquitousContentNameKey: storeName} error:&error];
Работает со всеми версиями.Передайте имя объекта и выполните итерацию, чтобы удалить все записи и сохранить контекст.
func deleteData(entityToFetch: String, completion: @escaping(_ returned: Bool) ->()) {
var context = NSManagedObjectContext()
if #available(iOS 10.0, *) {
context = self.persistentContainer.viewContext
} else {
context = self.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)")
}
}
Вот версия, которая удаляет каждую запись в каждой вашей таблице.
Свифт 4
static func resetDatabase() {
do {
try dataStore.persistentStoreCoordinator.managedObjectModel.entities.forEach { (entity) in
if let name = entity.name {
let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: name)
let request = NSBatchDeleteRequest(fetchRequest: fetch)
try mainContext.execute(request)
}
}
try mainContext.save()
} catch {
print("error resenting the database: \(error.localizedDescription)")
}
}
Удалить файл постоянного хранилища и настроить нового координатора постоянного хранилища?
Удалите sqlite из вашего fileURLPath, а затем создайте.
Предполагая, что вы используете MagicalRecord
и иметь хранилище персистентности по умолчанию:
Мне не нравятся все решения, которые предполагают существование определенных файлов и/или требуют ввода имен или классов объектов.Это безопасный способ Swift(2) удалить все данные со всех объектов.После удаления он также воссоздаст новый стек (на самом деле я не уверен, насколько необходима эта часть).
Это годо для ситуаций в стиле «выход из системы», когда вы хотите удалить все, но у вас есть работающее хранилище и moc для получения новых данных (как только пользователь входит в систему...)
extension NSManagedObject {
class func dropAllData() {
MagicalRecord.saveWithBlock({ context in
for name in NSManagedObjectModel.MR_defaultManagedObjectModel().entitiesByName.keys {
do { try self.deleteAll(name, context: context) }
catch { print("⚠️ ✏️ Error when deleting \(name): \(error)") }
}
}) { done, err in
MagicalRecord.cleanUp()
MagicalRecord.setupCoreDataStackWithStoreNamed("myStoreName")
}
}
private class func deleteAll(name: String, context ctx: NSManagedObjectContext) throws {
let all = NSFetchRequest(entityName: name)
all.includesPropertyValues = false
let allObjs = try ctx.executeFetchRequest(all)
for obj in allObjs {
obj.MR_deleteEntityInContext(ctx)
}
}
}
Использовать это
+(NSArray *)fetchDataFromEntity:(NSString *)entityName context:(NSManagedObjectContext *)context
{
NSFetchRequest * fetchRequest =[[NSFetchRequest alloc] init];
NSEntityDescription * CategoriesEntity = [NSEntityDescription entityForName:entityName inManagedObjectContext:context];
[fetchRequest setEntity:CategoriesEntity];
NSError * error;
NSInteger count = [context countForFetchRequest:fetchRequest error:&error];
if (count && count>0) {
NSArray * fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects && fetchedObjects.count>0) {
return fetchedObjects;
}else
return nil;
}
else
return nil;
}
+ (void)deleteObjectsOfArray:(NSMutableArray*)ary context:(NSManagedObjectContext *)context {
for (NSManagedObject * obj in ary) {
[context deleteObject:obj];
}
NSError *saveError = nil;
[context save:&saveError];
}
+ (void)deleteEntity:(NSString *)entityName context:(NSManagedObjectContext *)context {
NSArray *listArray = [self fetchDataFromEntity:entityName context:context];
[self deleteObjectsOfArray:[NSMutableArray arrayWithArray:listArray] context:context];
}
Я взял код Граучаля и для его ускорения использовал перечисление в параллельном режиме (NSEnumerationConcurrent
), он стал немного быстрее по сравнению с циклом for (в своем приложении я добавил эту функцию для тестировщиков, чтобы они могли очищать данные и выполнять тестовые случаи, а не удалять и устанавливать приложение)
- (void)resetObjects
{
[self deleteAllObjectsInEntity:@"Entity1"];
[self deleteAllObjectsInEntity:@"Entity2"];
[self deleteAllObjectsInEntity:@"Entity3"];
[self deleteAllObjectsInEntity:@"Entity4"];
}
-(void) deleteAllObjectsInEntity:(NSString*) entityName
{
MainDataContext *coreDataContext = [MainDataContext sharedInstance];
NSManagedObjectContext *currentContext = coreDataContext.managedObjectContext;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:currentContext];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *items = [currentContext executeFetchRequest:fetchRequest error:&error];
[items enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSManagedObject * obj, NSUInteger idx, BOOL *stop) {
[currentContext deleteObject:obj];
}];
if (![currentContext save:&error]) {
NSLog(@"Error deleting %@ - error:%@",entityName,error);
}
}
вот моя версия Swift3 для удаления всех записей.«Пользователи» — это имя объекта.
@IBAction func btnDelAll_touchupinside(_ sender: Any) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedObjectContext = appDelegate.persistentContainer.viewContext
let fetchReq = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
let req = NSBatchDeleteRequest(fetchRequest: fetchReq)
do {
try managedObjectContext.execute(req)
} catch {
// Error Handling
}
}
iOS 10 и Свифт 3
Предполагая, что имя вашей сущности — «Фото» и вы создаете класс CoreDataStack...
func clearData() {
do {
let context = CoreDataStack.sharedInstance.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Photo")
do {
let objects = try context.fetch(fetchRequest) as? [NSManagedObject]
_ = objects.map{$0.map{context.delete($0)}}
CoreDataStack.sharedInstance.saveContext()
} catch let error {
print("ERROR DELETING : \(error)")
}
}
}
Вот хорошее руководство о том, как использовать CoreData и как использовать этот метод.https://medium.com/compileswift/parsing-json-response-and-save-it-in-coredata-step-by-step-fb58fc6ce16f#.1tu6kt8qb
Еще один метод (помимо пакетного запроса на удаление), который я часто использую (в зависимости от требований приложения), — это сброс постоянного хранилища.Реализация для iOS 10+ и Swift выглядит следующим образом (при условии, что у вас есть класс CoreDataManager):
let persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "<Data-Model-Name>“)
container.loadPersistentStores(completionHandler: { (storeDescription, err) in
if let err = err {
fatalError("loading of store failed: \(err)")
}
})
return container
}()
func resetPersistentStore() {
if let persistentStore = persistentContainer.persistentStoreCoordinator.persistentStores.last {
let storeURL = persistentContainer.persistentStoreCoordinator.url(for: persistentStore)
do {
try persistentContainer.persistentStoreCoordinator.destroyPersistentStore(at: storeURL, ofType: NSSQLiteStoreType, options: nil)
} catch {
print("failed to destroy persistent store:", error.localizedDescription)
}
do {
try persistentContainer.persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: nil)
} catch {
print("failed to re-add persistent store:", error.localizedDescription)
}
}
}
Одним из преимуществ этого метода является то, что он более прост, особенно если у вас есть множество записей данных для множества объектов в ваших основных данных.В этом случае пакетный запрос на удаление будет занимать много памяти.
вы все усложняете ситуацию.Вы можете просто отправить NSManagedObjectContext метод сброса.