2012-06-23 12 views
15

मैं initWithContentsOfURL के साथ एक NSManagedObjectModel मॉडल लोड हो रहा हूँ: निर्माता इस तरह:लोड एक पिछले मॉडल संस्करण

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyDocument" withExtension:@"momd"]; 
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 

हालांकि यह केवल मुझे एक मॉडल के नवीनतम/वर्तमान संस्करण में पहुँच देता है। क्या पिछले संस्करणों को उसी momd फ़ाइल के साथ लोड करना उचित है? कैसे?

उत्तर

32

वास्तव में आप के साथ एक पुराने संस्करण लोड कर सकते हैं:

- (NSManagedObjectModel *)managedObjectModelForVersion:(NSString *)version 
{ 
     NSURL *modelURL = [[NSBundle mainBundle] URLForResource:[NSString stringWithFormat:@"AppModel.momd/AppModel %@",version] withExtension:@"mom"]; 
     NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 
     return model; 
} 

बस अपने मॉडल नाम वाला AppModel बदलें।

मैं इसका उपयोग iCloud से चिपकने वाली चिपचिपा मैन्युअल माइग्रेशन स्थिति से बाहर निकलने के लिए कर रहा हूं। उच्च और निम्न खोजे और इसे कहीं भी नहीं मिला।

+0

मेरे संस्करण (7.1) संस्करण पर fyi संस्करण। Mom (ओं) संस्करण के समान नाम वाली फ़ाइल में हैं (इसलिए @ "... /% @", संस्करण के बजाय संस्करण "/.../ AppModel% @ ", संस्करण) –

-2

नहीं, यह पूर्ववत नहीं है कि यह संभव है। मैं अनुमान है कि NSManagedObjectModeldocumentation, जहां यह संपत्ति versionIdentifiers पर चर्चा कहते हैं से:

यह मान मदद करने के लिए आप मॉडल है कि किसी मर्ज किए गए मॉडल बनाने के लिए संयुक्त रहे थे निर्धारित एक डिबगिंग संकेत के रूप में इस्तेमाल किया जा करने के लिए है।

तो ऐसा प्रतीत नहीं होता कि आपको अपने प्रोग्राम तर्क के लिए पिछले मॉडल संस्करणों का उपयोग करना चाहिए।

+0

आप सामान्य रूप से कस्टम माइग्रेशन कैसे करते हैं? अस्थायी रूप से इसे हल करने के लिए मैं अपने डेटा मॉडल (जिसमें सभी संस्करणों को दोबारा शामिल किया गया है) के लिए फ़ोल्डर की एक प्रति बनाते हैं और पुराने संस्करण के रूप में सेट किया गया है जिसे मैं समर्थन देना चाहता हूं। इस तरह से मैं NSManagedObjectModel के पुराने और नए उदाहरणों का निर्माण कर सकता हूं जिन्हें मुझे NSMigrationManager – SystematicFrank

+0

की आवश्यकता है, मैं इससे सहमत नहीं हूं। कृपया मेरा जवाब देखें। – Schoob

3

तुम सिर्फ मॉडल एक विशेष मौजूदा दुकान की कोशिश के साथ संगत है के संस्करण लोड करने के लिए करना चाहते हैं:

NSError *error = nil; 
NSDictionary *storeMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType 
                         URL:storeURL 
                         error:&error]; 
NSManagedObjectModel *oldManagedObjectModel = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:[NSBundle mainBundle]] 
                      forStoreMetadata:storeMetadata]; 

ध्यान दें कि आप अपने डेटा मॉडल संस्करणों के लिए XCode संस्करण पहचानकर्ता का उपयोग करता है, तो, लगातार दुकान के वर्तमान संस्करण पहचान मेटाडाटा शब्दकोश में NSStoreModelVersionIdentifiersKey प्रविष्टि के माध्यम से पहचानकर्ता सुलभ हैं।

जहां तक ​​एक विशेष मनमाना संस्करण लोड करना है, माँ फाइलें आम तौर पर आपके ऐप के बंडल में माँ निर्देशिका में स्थित होती हैं, ताकि आप NSFileManager का उपयोग करके उन्हें समझा सकें। मुझे लगता है कि एक विशेष संस्करण पहचानकर्ता के साथ आपको ढूंढने के लिए आपको एनएसएमएनेज्डऑबजेक्ट मॉडेल के initWithContentsOfURL का उपयोग करना होगा: प्रारंभकर्ता और उसके बाद संस्करण इन्टेंटिफ़ायर प्रॉपर्टी का निरीक्षण करें, या कॉन्फ़िगरेशन का उपयोग करें: संगत WithStoreMetadata: संगतता निर्धारित करने के लिए उदाहरण विधि।

+0

और एक शून्य स्टोर मेटाडेटा की जांच करें, जिस स्थिति में आपको मौजूदा डेटाबेस नहीं मिला है, इसलिए इसे बनाने की आवश्यकता है! –

2

@Schoob द्वारा श्रेणी में solution की पेशकश की गई, क्योंकि वे रॉक करते हैं।

@interface NSManagedObjectModel (version) 
+ (NSManagedObjectModel *)modelFromBundle:(NSBundle *)bundle name:(NSString *)modelName version:(NSString *)version; 
@end 

@implementation NSManagedObjectModel (version) 
+ (NSManagedObjectModel *)modelFromBundle:(NSBundle *)bundle name:(NSString *)modelName version:(NSString *)version 
{ 
    if(!bundle) 
     bundle = [NSBundle mainBundle]; 

    NSString *resource = [[modelName stringByAppendingPathExtension:@"momd"] stringByAppendingPathComponent:version]; 
    NSURL *modelURL = [bundle URLForResource:resource withExtension:@"mom"]; 
    NSAssert(modelURL,@"Unable to find MOM - %@",resource); 
    NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 
    NSAssert(model,@"Unable to load MOM at URL- %@",modelURL); 
    return model; 
} 
@end 
0

स्विफ्ट संस्करण। फ़ाइल नाम बदलें।

import CoreData 

extension NSManagedObjectModel 
{ 
    class func model(forVersion version: Int) -> NSManagedObjectModel? 
    { 
     if let fileUrl = Bundle.main.url(forResource: "Model.momd/Model \(version)", withExtension: "mom") 
     { 
      return NSManagedObjectModel(contentsOf: fileUrl) 
     } 
     return .none 
    } 
} 
संबंधित मुद्दे