कोर डेटा में सभी प्रविष्टियों को हटाएं / रीसेट करें?


235

क्या आप कोर डेटा में संग्रहीत सभी प्रविष्टियों को हटाने का कोई तरीका जानते हैं? मेरा स्कीमा वही रहना चाहिए; मैं बस इसे खाली करने के लिए रीसेट करना चाहता हूं।


संपादित करें

मैं इस प्रोग्राम को ऐसा करने के लिए देख रहा हूं ताकि उपयोगकर्ता अनिवार्य रूप से एक resetबटन दबा सके।


6
नीचे दिए गए कई उत्तर दिनांकित हैं। का उपयोग करें NSBatchDeleteRequeststackoverflow.com/a/31961330/3681880
Suragch

जवाबों:


198

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 में बाहरी बाइनरी स्टोरेज की अनुमति देता है (बाह्य बाह्य फ़ाइल में स्टोरेज या एक्सटर्नल रिकॉर्ड फ़ाइल में), केवल storeurLs द्वारा बताई गई फ़ाइलों को हटाने के लिए पर्याप्त नहीं है। आप बाहरी रिकॉर्ड फ़ाइलों को पीछे छोड़ देंगे। चूंकि इन बाहरी रिकॉर्ड फ़ाइलों की नामकरण योजना सार्वजनिक नहीं है, इसलिए मेरे पास अभी तक एक सार्वभौमिक समाधान नहीं है। - 0 मई 8 '12 23:00 बजे


1
यह शायद विश्वसनीयता के लिए सबसे अच्छा समाधान है। यदि मैं कुछ डेटा को नहीं, बल्कि सभी को हटाना चाहता था, तो मैं इसका उपयोग करूंगा: stackoverflow.com/questions/1077810/…
माइकल ग्रिनिच

12
मुझे पता है कि स्टोरकोर्डिनेटर को ठीक से कैसे प्राप्त किया जाए। हालांकि मैं नहीं जानता कि कैसे लगातार प्राप्त करने के लिए। तो क्या आप कृपया इसके बजाय एक उचित उदाहरण दे सकते हैं: NSPersistentStore * store = ...;
पास्कल क्लेन

11
[[NSFileManager defaultManager] removeItemAtURL: storeURL त्रुटि: और त्रुटि] बेहतर है।
AN0

3
@ पास्कल यदि आप स्टोर कोऑर्डिनेटर प्राप्त कर सकते हैं तो यो को अपने सभी स्थायी स्टोरों में लगातार संपत्ति के माध्यम से पहुंच प्राप्त होती है।
मिहाई दामियन

2
उदाहरण कोड जिसमें एक नया खाली स्टोर फिर से बनाना है: stackoverflow.com/a/8467628
जोशुआ सी। लर्नर

140

आप 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);
    }

}

जिस कारण से मैंने इसे टेबल द्वारा टेबल करने के लिए चुना वह यह है कि यह मुझे पुष्टि करता है क्योंकि मैं प्रोग्रामिंग कर रहा हूं कि टेबल की सामग्री को हटाना समझदार है और ऐसा कोई डेटा नहीं है जिसे मैं रखूंगा।

ऐसा करने से फ़ाइल को हटाने की तुलना में यह बहुत धीमी हो जाएगी और अगर मैं इस विधि को बहुत लंबा लेता हूं, तो मैं फ़ाइल को हटा दूंगा।


महान समाधान। धन्यवाद। DLog () क्या है?
माइकल ग्रिनिच

आह हाँ - क्षमा करें कि एक विशेष कार्य है जिसका उपयोग मैं केवल एक NSLog करता है जब निर्माण एक DEBUG का निर्माण होता है - बस NSLog के साथ बदलें।
ग्रोचल

6
आप यहां DLog का कार्यान्वयन देख सकते हैं: cimgf.com/2009/01/24/dropping-nslog-in-release-builds
मैट लॉन्ग

3
यह मेरे लिए अच्छी तरह से काम करता है। लेकिन इसे तेज करने के लिए, क्या एक निश्चित इकाई के सभी ऑब्जेक्ट को एक कमांड के साथ हटाने का एक तरीका है? जैसे SQL में आप कुछ कर सकते हैं, DROP TABLE unit_name। मैं संपूर्ण SQL फ़ाइल को हटाना नहीं चाहता क्योंकि मैं केवल एक विशिष्ट इकाई के सभी ऑब्जेक्ट को हटाना चाहता हूं, अन्य संस्थाओं को नहीं।
ma11hew28

8
NS सहारे का उपयोग करें * allEntities = _managedObjectModel.entitiesByName; अपने मॉडल में सभी संस्थाओं को प्राप्त करने के लिए और फिर आप स्टोर में सभी संस्थाओं को शुद्ध करने के लिए इस एनएसडीआर में कुंजियों पर पुनरावृति कर सकते हैं।
adam0101

60

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 और स्विफ्ट 3 के लिए अपडेट किया गया है। यदि आपको iOS 9 का समर्थन करने की आवश्यकता है, तो यह प्रश्न देखें ।

सूत्रों का कहना है:


3
मैं उस पूरे ब्लॉक को एक moc.performBlockAndWait({ () -> Void in... के अंदर रखूँगा })
स्विफ्टआर्किटेक्ट

2
सुनिश्चित करें कि आप देखते हैं कि एप्लिकेशन पुनः आरंभ होने तक प्रविष्टियां क्यों नहीं हटाई जाती हैं या मैं अपने NSBatchDeleteRequest को दो बार निष्पादित करता हूं? उपरोक्त कोड लंबी कहानी पर्याप्त नहीं है अगर संस्थाओं को मेमोरी में लोड किया जाता है
हनी

38

मैंने एक 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वर्ग के अंदर है जो (अन्य चीजों के बीच) देखभाल करता है जब वह शून्य होता है, तो निरंतर स्ट्रेचर का निर्माण करता है।


"चयनकर्ता के लिए कोई ज्ञात वर्ग विधि 'लगातार नहीं'"
अविराम नेतनल

27

मैं एक बटन पर कोर डेटा से सभी डेटा को हटाता हूं एक होमव्यूकंट्रोलर इवेंट में घटना: इस लेख ने मुझे इतना मदद की कि मुझे लगा कि मैं योगदान दूंगा।

-(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 को कॉल करने के लिए मैंने होम व्यू कंट्रोलर में एक संपत्ति घोषित की। (प्रबंधितObjectContext के बारे में चिंता न करें जो मैं बचत और लोड करने के लिए उपयोग करता हूं।)

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

@ayeat, यह काम आपके लिए किया है ?. मेरे लिए इसके काम नहीं करने के लिए, कृपया इस stackoverflow.com/questions/14646595/…
रणजीत

1
इसे "AppDelegate * ad = [[UIApplication साझाApplication] डेलीगेट]] का उपयोग करने के अलावा ANSWER है;" और विज्ञापन के साथ स्व को बदलें। और कोड के अंतिम दो बिट्स कॉपी न करें
Cescy

1
आप ManageObjectContext पर रीसेट क्यों नहीं कह रहे हैं? क्या होगा अगर आपके पास प्रबंधितओबजेक्ट के लिए कुछ मजबूत संदर्भ हैं?
पराग बाफना

@ParagBafna आप सही हैं, कोड नमूना ऊपर मान लिया गया है कि प्रबंधित वस्तुओं का कोई मजबूत संदर्भ नहीं है। यदि आपके पास कुछ है, तो आपको ManageObjectContext पर 'रीसेट' को कॉल करना चाहिए और आपके पास मौजूद किसी भी प्रबंधित ऑब्जेक्ट को डी-रेफरेंस करना चाहिए।
atreat

धन्यवाद। इसके अलावा, क्या ऐप अपग्रेड पर ऐसा करने का कोई तरीका है? सटीक होने के लिए, मेरी आवश्यकता तब होती है जब मैं अपने अगले संस्करण को रोल कर रहा होता हूं, उस समय जब उपयोगकर्ता ऐपस्टोर से अपने ऐप को अपडेट करता है, तो कोर डेटा एन स्क्वैलाइट फ़ाइलों को हटा दिया जाना चाहिए और रिक्त करने के लिए पुन: स्थापित किया जाना चाहिए। मैंने NSUserDefaults में एक बूल मान का उपयोग करके ऐप के पहले लॉन्च ईवेंट का पता लगाने का तरीका निकाला और ऐप डेलिगेट की didfinishLaunchingWithOptions में इस मान की जाँच की, लेकिन समझ नहीं आया कि इन सभी चीज़ों को कैसे साफ़ करें। चूंकि कोई बटन नहीं है और एप्लिकेशन प्रतिनिधि मेरे "persistentStore" का पता लगाने के लिए इसे स्पष्ट नहीं कर रहा है जैसा कि आपने ऊपर किया था। कोई मदद?
तेजस

19

MagicalRecord इसे बहुत आसान बनाता है।

[MyCoreDataObject MR_truncateAll];

16
यह एक अच्छा विषय है, लेकिन जब से मैंने
कोरडाटा

8
सक्रिय रिकॉर्ड ला रहा है है एक कोर डेटा समाधान।
शिक्षाविद

7
लेकिन इस तरह का एक उत्तर प्रश्न के दायरे से परे है। यह मानने का कोई कारण नहीं है कि वह ऐसा करने के लिए एक addt'l ढांचे का उपयोग करना चाहता है।
jpswain

मेरा तर्क है कि यह इस सवाल का जवाब नहीं देता है। यह एक इकाई से प्रविष्टियों को हटाने का एक अच्छा तरीका है, सभी संस्थाओं को नहीं ...! आप मॉडल में सभी संस्थाओं के माध्यम से कैसे गणना करते हैं और MR_truncateAllउन पर भेजते हैं?
फतुहोकू

MR_truncateAll के लिए स्रोत देखें - यह सभी ऑब्जेक्ट्स को प्राप्त करता है, लेकिन उनके गुणों को नहीं (जैसा कि हम NSMOs को छोड़ने का इरादा रखते हैं), फिर यह निर्दिष्ट इकाई के लिए ऑब्जेक्ट्स पर पुनरावृत्ति करता है और उन्हें हटा देता है। github.com/magicalpanda/MagicalRecord/blob/master/MagicalRecord/…
1in9ui5t

19

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

1
सुनिश्चित करें कि आप देखते हैं कि एप्लिकेशन पुनः आरंभ होने तक प्रविष्टियां क्यों नहीं हटाई जाती हैं या मैं अपने NSBatchDeleteRequest को दो बार निष्पादित करता हूं? उपरोक्त कोड लंबी कहानी पर्याप्त नहीं है यदि संस्थाओं को मेमोरी में लोड किया जाता है
हनी

13

[नए जवाब के लिए एक इनाम के जवाब में देर से जवाब]

पहले के जवाबों की तलाश में,

  • @Grouchal और अन्य लोगों द्वारा सुझाए गए सभी आइटम लाना और हटाना अभी भी एक प्रभावी और उपयोगी समाधान है। यदि आपके पास बहुत बड़े डेटा स्टोर हैं तो यह धीमा हो सकता है, लेकिन यह अभी भी बहुत अच्छा काम करता है।
  • बस डेटा स्टोर को हटाना, जैसा कि आप और @ अग्रहोग नोट, अब प्रभावी नहीं है। यदि आप बाहरी बाइनरी स्टोरेज का उपयोग नहीं करते हैं तो भी यह अप्रचलित है क्योंकि iOS 7 SQLite जर्नलिंग के लिए वाल मोड का उपयोग करता है। वाल मोड के साथ किसी भी कोर डेटा लगातार स्टोर के लिए आस-पास बैठे (संभावित रूप से बड़ी) जर्नल फाइलें हो सकती हैं।

लेकिन काम करने वाले लगातार स्टोर को हटाने के लिए एक अलग, समान दृष्टिकोण है। कुंजी आपकी अपनी उप-निर्देशिका में लगातार स्टोर फ़ाइल डालने की है जिसमें कुछ और नहीं है। इसे केवल दस्तावेज़ निर्देशिका (या जहां भी) में न रखें, केवल स्थिर स्टोर के लिए एक नई उप-निर्देशिका बनाएं। उस निर्देशिका की सामग्री लगातार स्टोर फ़ाइल, जर्नल फ़ाइलों और बाहरी बाइनरी फ़ाइलों के रूप में समाप्त हो जाएगी। यदि आप संपूर्ण डेटा स्टोर को न्यूड करना चाहते हैं, तो उस निर्देशिका को हटा दें और वे सभी गायब हो जाएंगे।

अपना स्थायी स्टोर स्थापित करते समय आप ऐसा कुछ करेंगे:

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

यह दृष्टिकोण त्रुटि प्रवण हो सकता है । आपको पूरी तरह से यकीन है कि आप हर उस फ़ाइल को जानते हैं जिसे आप रखना चाहते हैं, क्योंकि अन्यथा आप महत्वपूर्ण डेटा निकाल सकते हैं। दूसरी ओर, आप बाहरी बाइनरी फ़ाइलों को हटा सकते हैं वास्तव में उन्हें स्टोर करने के लिए उपयोग की जाने वाली फ़ाइल / निर्देशिका नाम को जानने के बिना।


यदि आप वाल फाइल से डरते हैं, तो इसे निष्क्रिय कर दें
onmyway133

11

कोर डेटा को शुद्ध करने के लिए यहां संयुक्त समाधान है।

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

10

यदि आप सभी ऑब्जेक्ट हटाना चाहते हैं और बैकिंग फ़ाइलों को हटाना नहीं चाहते हैं, तो आप निम्न विधियों का उपयोग कर सकते हैं:

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

खबरदार कि यह बहुत धीमा हो सकता है (यह निर्भर करता है कि आपके ऑब्जेक्ट ग्राफ में कितनी वस्तुएं हैं)।


ऐप अपडेट होने पर पुराने डेटा को कैसे हटाएं (तीन तालिकाएं, एक तालिका से मैं डेटा साफ़ करना चाहता हूं)
मदन मोहन

6

यदि आप सभी ऑब्जेक्ट्स रूट को हटाना चाहते हैं (जो कोर डेटा स्टैक को फाड़ने की तुलना में बहुत सरल है, लेकिन कम परफॉर्मेंट), तो यह बेहतर कार्यान्वयन है:

- (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मुख्य थ्रेड के विलोपन को पूरा करने और पूरा होने पर सूचित करने का लाभ उठाता है। आप मुख्य थ्रेड पर वापस स्थिति को बबल करने के लिए एक अधिसूचना या पूर्ण ब्लॉक के भीतर कुछ फेंकना चाह सकते हैं।


ध्यान रखें कि आपके NSManagedObjectContext की तरह प्रारंभ किया जाना चाहिए NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];या फिर इस विधि का उपयोग करने में आप त्रुटि मिलती है:Can only use -performBlock: on an NSManagedObjectContext that was created with a queue.
विल

6

iOS 10 + स्विफ्ट 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()
        }
    }
}

सभी मुख्य डेटा संस्थाओं के माध्यम से Iterates और उन्हें साफ़ करता है


4

पोस्ट के लिए धन्यवाद। मैंने इसका पालन किया और यह मेरे लिए काम कर गया। लेकिन मेरे पास एक और मुद्दा था जिसका किसी भी उत्तर में उल्लेख नहीं किया गया था। तो मुझे यकीन नहीं है कि अगर यह सिर्फ मैं था।

वैसे भी, मैंने सोचा कि मैं यहाँ समस्या और मेरे रास्ते को हल करूँगा।

डेटाबेस में मेरे कुछ रिकॉर्ड थे, मैं db को नया डेटा लिखने से पहले सब कुछ शुद्ध करना चाहता था, इसलिए मैंने सब कुछ शामिल किया

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

और तब managedObjectContextडेटाबेस का उपयोग किया जाता था (अब तक खाली होना चाहिए), किसी तरह डेटा अभी भी था। समस्या निवारण के थोड़ी देर के बाद, मैंने पाया कि मैं रीसेट करने की आवश्यकता managedObjectContext, managedObject, managedObjectModelऔर persistentStoreCoordinatorइससे पहले कि मैं का उपयोग करें, managedObjectContextdabase तक पहुँचने के लिए। अब मेरे पास लिखने के लिए एक साफ डेटाबेस है।


तो ManageObjectContext, ManageObject, ManageObjectModel और persistentStoreCoordinator को रीसेट करना फ़ाइल को डेटाबेस से हटाए जाने के बाद वापस रखता है?
डैनियल ब्राउनर

4

यहाँ कुछ हद तक सरलीकृत संस्करण है, जिसमें एपडेलगेट से कम कॉल और अंतिम बिट कोड है जो शीर्ष रेटेड उत्तर से बचा हुआ था। इसके अलावा, मुझे एक त्रुटि मिल रही थी "ऑब्जेक्ट का लगातार स्टोर इस 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];
}

4

तेजी से समाधान:

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

स्विफ्ट 2 के लिएlet modelURL = NSBundle.mainBundle().URLForResource("some string", withExtension: "momd")!
Saorikido

3

कहीं और खोजने से बचाने के लिए एक त्वरित संदर्भ के रूप में - इसे हटाने के बाद लगातार स्टोर को फिर से बनाना:

if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
// do something with the error
}

मैंने आपके कोड की कोशिश की, लेकिन इस लाइन पर एक्सकोड एक अपवाद फेंकता है, इसलिए आपको इस बारे में क्या कहना है।
रणजीत

3

इस सवाल के कई अच्छे जवाब। यहाँ एक अच्छा संक्षिप्त है। पहली दो पंक्तियाँ sqlite डेटाबेस को हटाती हैं। तब के लिए: लूप किसी ऑब्जेक्ट को प्रबंधित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];
}

1
इस उद्देश्य के लिए प्रतिनिधिमंडल का दुरुपयोग न करें: hollance.com/2012/02/dont-abuse-the-app-delegate
माइकल

1
मैं @MichaelDorner से सहमत हूं। AppDelegate में बहुत कुछ जोड़ना प्रदर्शन को प्रभावित कर सकता है और आपके द्विआधारी के आकार को एक निर्भर मकड़ियों की निर्भरता के साथ उड़ा सकता है जहाँ AppDelegate को अचानक हर वर्ग में शामिल करने की आवश्यकता होती है। यदि आप इसे काटते हुए पाते हैं, तो इस उद्देश्य के लिए एक अलग नियंत्रक बनाएँ। AppDelegate को मूल इनिशियलाइज़ेशन के लिए रहना चाहिए और एप्लिकेशन में राज्य परिवर्तनों को हैंडल करना चाहिए, बहुत अधिक नहीं।
jcpennypincher

2

आप सभी इकाई नाम भी पा सकते हैं, और उन्हें नाम से हटा सकते हैं। इसका लंबा संस्करण है, लेकिन अच्छी तरह से काम करता है, इस तरह से आपको दृढ़ता के साथ काम नहीं करना पड़ता है

 - (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 @ "नाम" सभी इकाई नाम वापस कर देगा। अंत में, बचाने के लिए मत भूलना।


2

NSFileManager द्वारा URL को हटाने के साथ स्वीकृत उत्तर सही है, लेकिन जैसा कि iOS 5+ एडिट में कहा गया है, लगातार स्टोर केवल एक फ़ाइल द्वारा प्रस्तुत नहीं किया गया है। SQLite स्टोर के लिए यह * .sqlite, * .sqlite-shm और * .sqlite-wal है ... सौभाग्य से iOS 7+ के बाद से हम विधि का उपयोग कर सकते हैं।

[NSPersistentStoreCoordinator + removeUbiquitousContentAndPersistentStoreAtURL: विकल्प: त्रुटि:]

हटाने का ख्याल रखना, इसलिए कोड कुछ इस तरह होना चाहिए:

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

2
आपको विकल्पों को पारित करने की आवश्यकता है, विशेष रूप से स्टोर का नाम, जैसे: @ {NSPersistentStoreUbiquitousContentNameKey: @ "MyData"};
tomi44g

2

यहां एक संस्करण है जो आपके पास मौजूद प्रत्येक तालिका के प्रत्येक रिकॉर्ड को हटा देता है।

स्विफ्ट 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)")
    }
}

2

स्विफ्ट 4/5, iOS 9+

संपूर्ण 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()
    }
}

इसका उपयोग करने वाले किसी के लिए, ध्यान दें कि यह "पहली बार" दुर्घटनाग्रस्त हो जाएगा जब वहाँ कोई sql फ़ाइल नहीं है (मैंने अपने उत्तर में "गार्ड" का उपयोग किया है)
Fattie

1

सभी संस्करणों के साथ काम करता है। सभी प्रविष्टियों को हटाने और संदर्भ को बचाने के लिए इकाई नाम और पुनरावृति पास करें।

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

1

एक अन्य विधि (एक डिलीट बैच अनुरोध के अलावा) मैं अक्सर उपयोग करता हूं (ऐप आवश्यकता के आधार पर) लगातार स्टोर को रीसेट करना है। कार्यान्वयन iOS 10+ और स्विफ्ट के लिए इस तरह दिखता है (यह मानते हुए कि आपके पास 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)
        }
    }

}

इस पद्धति का एक फायदा यह है कि यह अधिक सीधा है, खासकर जब आपके पास अपने मुख्य डेटा में कई संस्थाओं के लिए डेटा रिकॉर्ड का भार होता है। जिस स्थिति में एक डिलीट बैच अनुरोध स्मृति गहन होगा।


1

स्विफ्ट 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)
    }
}

0

लगातार स्टोर फ़ाइल को हटाएं और एक नया लगातार स्टोर समन्वयक सेटअप करें?


6
साफ सफाई करने से लगातार स्टोर की गई फाइलें नहीं हटेंगी, शुक्र है। अगर यह सच है तो आपदा के लिए एक नुस्खा होगा।
हंटर


0

मान लें कि आप उपयोग कर रहे हैं MagicalRecordऔर एक डिफ़ॉल्ट दृढ़ता स्टोर है:

मैं उन सभी समाधानों को पसंद नहीं करता जो कुछ फ़ाइलों को अस्तित्व में रखते हैं और / या संस्थाओं के नाम या कक्षाओं में प्रवेश करने की मांग करते हैं। यह एक स्विफ्ट (2) है, सभी संस्थाओं से सभी डेटा को हटाने का सुरक्षित तरीका है। इसे हटाने के बाद एक ताजा स्टैक भी फिर से बनाया जाएगा (मुझे वास्तव में यकीन नहीं है कि यह हिस्सा कितना पुराना है)।

यह "लॉगआउट" शैली की स्थितियों के लिए गोडो है जब आप सब कुछ हटाना चाहते हैं, लेकिन नया डेटा प्राप्त करने के लिए एक कार्यशील स्टोर और मॉक है (एक बार उपयोगकर्ता लॉग इन ...)

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

    }
}

0

इसे इस्तेमाल करो

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

0

मैंने ग्रोचल का कोड लिया और इसे गति देने के लिए मैंने समवर्ती मोड ( 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);
    }
}

0

यहाँ सभी रिकॉर्ड को हटाने के लिए मेरे स्विफ्ट 3 संस्करण। 'उपयोगकर्ता' संस्था का नाम है

@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
    }   
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.