[iphone] حذف / إعادة تعيين جميع الإدخالات في البيانات الأساسية؟


Answers

يمكنك حذف ملف sqllite - لكنني اخترت القيام بذلك عن طريق إزالة الجداول بشكل فردي بوظائف:

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

}

السبب الذي جعلني أختار القيام بذلك الجدول حسب الجدول هو أنه يجعلني أؤكد أنني أقوم بالبرمجة بأن حذف محتويات الجدول أمر معقول وليس هناك أي بيانات أود الاحتفاظ بها.

القيام بذلك سيكون أبطأ بكثير من مجرد حذف الملف وسوف أتغير إلى حذف ملف إذا استغرقت هذه الطريقة وقتا طويلا.

Question

هل تعرف بأي طريقة لحذف جميع الإدخالات المخزنة في Core Data؟ يجب أن يبقى المخطط الخاص بي كما هو ؛ أنا فقط أريد إعادة تعيينه على فارغة.

تصحيح

أنا أتطلع إلى القيام بذلك برمجيًا حتى يتمكن المستخدم من الوصول إلى زر reset أساسي.




يمكنك أيضًا العثور على جميع أسماء الكيانات وحذفها حسب الاسم. لها نسخة أطول ولكن يعمل بشكل جيد ، وبهذه الطريقة لم يكن لديك للعمل مع مخزن استمرار

 - (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" بكافة أسماء الكيانات. وأخيرًا ، لا تنسَ الحفظ.




حل 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()
        }
    }
}

يتكرر من خلال جميع كيانات البيانات الأساسية ويخليها




بافتراض أنك تستخدم MagicalRecord ولديك مخزن استمرارية افتراضي:

لا أحب جميع الحلول التي تفترض وجود ملفات معينة و / أو المطالبة بإدخال أسماء أو فئات الكيانات. هذه طريقة سويفت (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)
        }

    }
}



إليك إصدار مبسط إلى حد ما مع مكالمات أقل إلى 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];
}



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



يعمل مع جميع الإصدارات. قم بتمرير اسم الكيان ثم قم بالتكرار لحذف جميع المدخلات وحفظ السياق.

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



هنا هو الحل المشترك لتطهير البيانات الأساسية.

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



أخذت رمز Grouchal وسرعته أنا استخدم التعداد مع الوضع المتزامن ( 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);
    }
}



MagicalRecord يجعل هذا سهل للغاية.

[MyCoreDataObject MR_truncateAll];



شكرا لهذا المنصب. تابعت ذلك وعملت لي. لكن لدي مشكلة أخرى لم يتم ذكرها في أي من الردود. ﻟذا ، ﻟﺳت ﻣﺗﺄﻛدًا ﻣﻣﺎ إذا ﻛﺎن ﻟﻲ ﻓﻘط.

على أي حال ، أعتقد أنني سأقوم بنشر المشكلة هنا وطريقي التي حلت ذلك.

كان لدي بعض السجلات في قاعدة البيانات ، أردت تطهير كل شيء نظيفًا قبل كتابة بيانات جديدة إلى db ، لذلك فعلت كل شيء بما في ذلك

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

ثم استخدم managedObjectContext للوصول إلى قاعدة البيانات (من المفترض أن تكون فارغة الآن) ، بطريقة ما كانت البيانات لا تزال موجودة. بعد فترة من تحرّي الخلل وإصلاحه ، اكتشفت أنني بحاجة إلى إعادة ضبط managedObjectContext و managedObject و managedObjectModel و persistentStoreCoordinator ، قبل أن أستخدم managedObjectContext للوصول إلى dabase. الآن لدي قاعدة بيانات نظيفة للكتابة عليها.




لقد كتبت طريقة 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 الذي يعتني (من بين أشياء أخرى) إنشاء persistentStore عندما لا يكون.




هل تريد حذف ملف المتجر الدائم وإعداد منسق متجر مستمر جديد؟




iOS 10 و Swift 3

بافتراض أن اسم الكيان هو "Photo" ، وأنك تقوم بإنشاء فئة 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




Related