programing

핵심 데이터의 모든 항목을 삭제/재설정하시겠습니까?

megabox 2023. 5. 29. 10:28
반응형

핵심 데이터의 모든 항목을 삭제/재설정하시겠습니까?

코어 데이터에 저장된 모든 항목을 삭제할 수 있는 방법을 알고 있습니까?스키마는 그대로 유지되어야 합니다. 공백으로 재설정하고 싶습니다.


편집

사용자가 기본적으로 다음을 누를 수 있도록 프로그래밍 방식으로 이 작업을 수행하려고 합니다.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+용 업데이트

외부 이진 스토리지의 도입으로 (허용)iOS 5 및 OS X 10.7의 외부 이진 데이터 저장 또는 외부 레코드 파일에 저장), 단순히 저장소별로 지정된 파일 삭제URL이 충분하지 않습니다.외부 기록 파일을 남겨둡니다.이러한 외부 레코드 파일의 이름 지정 체계가 공개되지 않았기 때문에, 저는 아직 범용 솔루션을 가지고 있지 않습니다.2012년 5월 8일 23시에

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 {
    print(error.localizedDescription)
}

이 코드는 iOS 10과 Swift 3용으로 업데이트되었습니다.iOS 9를 지원해야 하는 경우 이 질문을 참조하십시오.

출처:

내가쓴것을 .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영(0)일 때 영구 저장소를 생성하는 것을 처리하는 클래스입니다.

HomeViewController 클래스의 Event(이벤트) 버튼을 사용하여 코어 데이터에서 모든 데이터를 제거합니다.이 기사는 저에게 많은 도움이 되었고, 저는 제가 기여할 것이라고 생각했습니다.

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

}

자기 자신을 부르기 위해 참고하세요.persistentStoreCoordinator 홈뷰 컨트롤러에서 속성을 선언했습니다. (저장 및 로드에 사용하는 관리되는 ObjectContext에 대해 걱정하지 마십시오.)

@property (nonatomic, retain) NSManagedObjectContext        *   managedObjectContext;
@property (nonatomic, retain) NSPersistentStoreCoordinator  *   persistentStoreCoordinator;

그런 다음 AppDelegate ApplicationDid 아래에서 HomeView 컨트롤러 생성을 완료했습니다.

homeViewController = [[HomeViewController alloc] initWithNibName:@"HomeViewController" bundle:nil];
homeViewController.managedObjectContext = self.managedObjectContext;
homeViewController.persistentStoreCoordinator = self.persistentStoreCoordinator;

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

매지컬 레코드는 이것을 매우 쉽게 만듭니다.

[MyCoreDataObject MR_truncateAll];

[새로운 응답을 요청하는 현상금에 대한 답변이 늦었습니다.]

이전 답변을 검토해 보면,

  • @Grouchal 등이 제안한 것처럼 모든 항목을 가져오고 삭제하는 것은 여전히 효과적이고 유용한 해결책입니다.데이터 저장소가 매우 큰 경우 속도가 느릴 수 있지만 여전히 매우 잘 작동합니다.
  • @groundhog와 마찬가지로 단순히 데이터 저장소를 제거하는 것은 더 이상 효과적이지 않습니다.iOS 7은 SQLite 저널링에 WAL 모드를 사용하기 때문에 외부 바이너리 스토리지를 사용하지 않더라도 구식입니다.WAL 모드에서는 코어 데이터 영구 저장소에 대한 저널 파일(대용량일 수 있음)이 저장될 수 있습니다.

하지만 작동하는 영구 저장소를 제거하는 데는 다른 유사한 접근 방식이 있습니다.중요한 것은 영구 저장소 파일을 다른 내용이 포함되지 않은 자체 하위 디렉터리에 저장하는 것입니다.문서 디렉토리(또는 다른 곳)에만 저장하지 말고 영구 저장소에 대한 새 하위 디렉토리를 만듭니다.해당 디렉터리의 내용은 영구 저장소 파일, 저널 파일 및 외부 이진 파일이 됩니다.전체 데이터 저장소를 삭제하려면 해당 디렉터리를 삭제하면 해당 디렉터리가 모두 사라집니다.

영구 저장소를 설정할 때 다음과 같은 작업을 수행할 수 있습니다.

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];

그러면 사용자 지정 하위 디렉터리와 디렉터리에 있는 모든 코어 데이터 파일이 모두 재귀적으로 제거됩니다.

이 기능은 다른 중요한 데이터와 동일한 폴더에 영구 저장소가 아직 없는 경우에만 작동합니다.다른 유용한 내용이 들어 있는 문서 디렉터리와 같은 것입니다.이 경우 보관할 파일을 찾고 다른 모든 파일을 제거하여 동일한 효과를 얻을 수 있습니다.다음과 같은 것:

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

모든 개체를 삭제하고 백업 파일을 삭제하지 않으려면 다음 방법을 사용할 수 있습니다.

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

개체 그래프의 개체 수에 따라 매우 느릴 수 있습니다.

모든 개체 삭제 경로(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()
        }
    }
}

모든 핵심 데이터 엔티티를 반복하여 삭제합니다.

Swift 4/5, iOS 9+

재성구체전▁the.CoreDataSQLite 파일은 모든 데이터를 삭제하므로 모든 엔티티가 삭제됩니다.그냥 전화하세요.deleteAndRebuild().

class CoreDataStack {
    // Change this
    static let datamodelName = "ProjectName"
    static let storeType = "sqlite"

    static let persistentContainer = NSPersistentContainer(name: datamodelName)
    private static let url: URL = {
        let url = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0].appendingPathComponent("\(datamodelName).\(storeType)")

        assert(FileManager.default.fileExists(atPath: url.path))

        return url
    }()

    static func loadStores() {
        persistentContainer.loadPersistentStores(completionHandler: { (nsPersistentStoreDescription, error) in
            if let error = error {
                fatalError(error.localizedDescription)
            }
        })
    }

    static func deleteAndRebuild() {
        try! persistentContainer.persistentStoreCoordinator.destroyPersistentStore(at: url, ofType: storeType, options: nil)

        loadStores()
    }
}

게시물 감사합니다.저는 그것을 따랐고 그것은 저에게 효과가 있었습니다.하지만 저는 어떤 답변에도 언급되지 않은 또 다른 문제가 있었습니다.그래서 저만 그런 건지 잘 모르겠어요.

어쨌든, 저는 여기에 문제와 그것을 해결한 저의 방식을 게시할 것이라고 생각했습니다.

데이터베이스에 몇 개의 레코드가 있습니다. 데이터베이스에 새 데이터를 쓰기 전에 모든 것을 정리하고 싶어서 다음을 포함한 모든 작업을 수행했습니다.

[[NSFileManager defaultManager] removeItemAtURL:storeURL error:&error]; 

그리고 사용되었습니다.managedObjectContext데이터베이스에 액세스하기 위해(지금은 비어 있을 것으로 예상됨), 어떻게든 데이터가 남아 있었습니다.해결한 에 다시 설정해야 것을 되었습니다.managedObjectContext,managedObject,managedObjectModel그리고.persistentStoreCoordinator사하기전에를 managedObjectContext데이터베이스에 액세스할 수 있습니다.이제 쓸 깨끗한 데이터베이스가 있습니다.

다음은 AppDelegate 자체에 대한 호출 수가 적고 최상위 응답에서 제외된 마지막 코드 부분이 포함된 다소 단순화된 버전입니다.또한 "이 NSManagedObjectContext의 코디네이터에서 Object의 영구 저장소에 연결할 수 없습니다."라는 오류가 발생하여 이를 다시 추가해야 했습니다.

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
}

이 질문에 대한 몇 가지 좋은 대답.여기 간결하고 멋진 것이 있습니다.처음 두 줄은 sqlite 데이터베이스를 삭제합니다.그런 다음 for: 루프는 관리되는 ObjectContext 메모리의 모든 개체를 삭제합니다.

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

여기 있는 모든 테이블의 모든 레코드를 삭제하는 버전이 있습니다.

스위프트 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)")
    }
}

또한 모든 엔터티 이름을 찾고 이름별로 삭제할 수 있습니다.더 긴 버전이지만 잘 작동합니다. 그래야 지속성 저장소에서 작업할 필요가 없습니다.

 - (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"은 모든 엔티티 이름을 반환합니다.마지막으로, 저장하는 것을 잊지 마세요.

NSFileManager에서 URL을 제거하는 것이 정답이지만 iOS 5+ edit에서 언급한 것처럼 영구 저장소는 하나의 파일로만 표현되지 않습니다.SQLite 저장소의 경우 *.sqlite, *.sqlite-shm 및 *.sqlite-wal...다행히 iOS 7+ 이후로 우리는 방법을 사용할 수 있습니다.

[NSPersistentStoreCoordinator +removeUbiquitousContentAndPersistentStoreAtURL:options:error:]

제거를 처리하기 위해 코드는 다음과 같아야 합니다.

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];

배치 삭제 요청과는 별도로, 앱 요구 사항에 따라 자주 사용하는 다른 방법은 영구 저장소를 재설정하는 것입니다.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)
        }
    }

}

이 방법의 한 가지 장점은 특히 코어 데이터에 있는 여러 엔티티에 대한 데이터 레코드가 많은 경우 더 간단하다는 것입니다.이 경우 배치 삭제 요청은 메모리 집약적입니다.

Swift 5.1 솔루션

public static func reset() {
    let coordinator = _persistentContainer.persistentStoreCoordinator
    for store in coordinator.persistentStores where store.url != nil {
        try? coordinator.remove(store)
        try? FileManager.default.removeItem(atPath: store.url!.path)
    }
}

모든 버전에서 작동합니다.엔티티 이름을 전달하고 반복하여 모든 항목을 삭제하고 컨텍스트를 저장합니다.

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

두 가지 접근 방식이 있는 것 같습니다.

코어 데이터 스택에 일반적인 싱글톤이 있다고 가정해 보겠습니다.

import CoreData
public let core = Core.shared
public final class Core {
    static let shared = Core()
    var container: NSPersistentContainer!
    private init() {
        container = NSPersistentContainer(name: "stuff")
        //deleteSql()
        container.loadPersistentStores { storeDescription, error in
            if let error = error { print("Error loading... \(error)") }
        }
        //deleteAll()
    }
    
    func saveContext() { // typical save helper
        if container.viewContext.hasChanges {
            do { try container.viewContext.save()
            } catch { print("Error saving... \(error)") }
        }
    }
    

그렇다면...

    func deleteSql() {
        let url = FileManager.default.urls(
           for: .applicationSupportDirectory,
           in: .userDomainMask)[0].appendingPathComponent( "stuff.sqlite" )
        
        guard FileManager.default.fileExists(atPath: url.path) else {
            print("nothing to delete!")
            return
        }
        
        do {
            try container.persistentStoreCoordinator.destroyPersistentStore(
                at: url, ofType: "sqlite", options: nil)
            print("totally scorched the sql file. you DO now have to LOAD again")
        }
        catch {
            print("there was no sql file there!")
        }
    }
    
    func deleteAll() { // courtesy @Politta
        for e in container.persistentStoreCoordinator.managedObjectModel.entities {
            let r = NSBatchDeleteRequest(
              fetchRequest: NSFetchRequest(entityName: e.name ?? ""))
            let _ = try? container.viewContext.execute(r)
        }
        saveContext()
        print("conventionally deleted everything from within core data. carry on")
    }
}

.

sql 파일을 태웁니다.

예의 그 훌륭한 @J.대답합니다.당신은 sql 파일을 완전히 파괴합니다.

작업을 수행해야 합니다.

  • 코어 데이터를 로드하기 전, 즉 컨테이너를 생성한 후,
  • (실제 저장소를 로드하기 전에).

(코드 "//deleteSql()"의 예제 행은 초기화 직전입니다.)

핵심 데이터 내의 모든 항목을 하나씩 삭제합니다.

예의: 훌륭한 @Politta 답변.코어 데이터가 실행되면 언제든지 이 작업을 수행할 수 있습니다.

(코드 "//deleteAll()"의 예제 행은 초기화 후입니다.)

하나의 접근 방식은 개발 중에 더 유용할 것입니다.두 번째 접근 방식은 생산에서 더 유용할 수 있습니다(어떤 이유로 인해 모든 것을 삭제해야 하는 비교적 드문 경우).

영구 저장소 파일을 삭제하고 새 영구 저장소 코디네이터를 설정하시겠습니까?

파일에서 sqlite 삭제URL 경로를 지정한 후 빌드합니다.

사용 중이라고 가정합니다.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), 루프에 비해 조금 빨라졌습니다(내 앱에서 나는 테스터가 앱을 삭제하고 설치하는 대신 데이터를 지우고 테스트 케이스를 수행할 수 있도록 이 기능을 추가했습니다).

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

언급URL : https://stackoverflow.com/questions/1077810/delete-reset-all-entries-in-core-data

반응형