मुझे पता लगा है कि Apple उनके प्रलेखन में क्या संकेत देता है । यह वास्तव में बहुत आसान है लेकिन स्पष्ट होने से पहले एक लंबा रास्ता तय करना है। मैं एक उदाहरण के साथ स्पष्टीकरण का वर्णन करता हूँ। प्रारंभिक स्थिति यह है:
डेटा मॉडल संस्करण 1
यह वह मॉडल है जो आपको तब मिलता है जब आप "नेविगेशन आधारित ऐप के साथ कोर डेटा स्टोरेज" टेम्पलेट बनाते हैं। मैंने इसे संकलित किया और कुछ अलग-अलग मूल्यों के साथ लगभग 2k प्रविष्टियों को बनाने के लिए लूप की मदद से कुछ कठिन हिट किया। वहाँ हम एक NSDate मान के साथ 2.000 ईवेंट जाते हैं।
अब हम डेटा मॉडल का दूसरा संस्करण जोड़ते हैं, जो इस तरह दिखता है:
डेटा मॉडल संस्करण 2
अंतर यह है: ईवेंट इकाई चली गई है, और हमें दो नए मिल गए हैं। एक जो एक टाइमस्टैम्प को एक के रूप में संग्रहीत करता है double
और दूसरा वह जो एक तिथि को स्टोर करना चाहिए NSString
।
लक्ष्य सभी संस्करण 1 को स्थानांतरित करना है ईवेंट को दो नई संस्थाओं में स्थानांतरित करना है और माइग्रेशन के साथ मूल्यों को परिवर्तित करना है। यह एक अलग इकाई में एक अलग प्रकार के रूप में प्रत्येक में दो बार मूल्यों का परिणाम है।
माइग्रेट करने के लिए, हम हाथ से माइग्रेशन चुनते हैं और यह हम मैपिंग मॉडल के साथ करते हैं। यह आपके प्रश्न के उत्तर का पहला भाग भी है। हम माइग्रेशन दो चरणों में करेंगे, क्योंकि 2k प्रविष्टियों को माइग्रेट करने में लंबा समय लग रहा है और हम मेमोरी फुटप्रिंट को कम रखना पसंद करते हैं।
तुम भी आगे जा सकते हैं और इन मानचित्रण मॉडल को विभाजित करने के लिए आगे संस्थाओं की केवल सीमाओं को स्थानांतरित कर सकते हैं। मान लीजिए कि हमें एक मिलियन रिकॉर्ड मिला, यह पूरी प्रक्रिया को ध्वस्त कर सकता है। यह एक फिल्टर विधेय के साथ नीचे भ्रूण संस्थाओं को संकीर्ण करने के लिए संभव है ।
हमारे दो मैपिंग मॉडल पर वापस जाएं।
हम इस तरह का पहला मैपिंग मॉडल बनाते हैं:
1. नई फाइल -> संसाधन -> मैपिंग मॉडल
2. एक नाम चुनें, मैंने StepOne को चुना
3. सेट स्रोत और गंतव्य डेटा मॉडल
मैपिंग मॉडल स्टेप वन
मल्टी पास माइग्रेशन के लिए कस्टम इकाई माइग्रेशन नीतियों की आवश्यकता नहीं होती है, हालांकि हम इस उदाहरण के लिए थोड़ा और विस्तार पाने के लिए ऐसा करेंगे। इसलिए हम इकाई में एक कस्टम नीति जोड़ते हैं। यह हमेशा एक उपवर्ग है NSEntityMigrationPolicy
।
यह नीति वर्ग हमारे प्रवासन को बनाने के लिए कुछ तरीकों को लागू करता है। लेकिन यह तो हम केवल एक विधि को लागू करना होगा इस मामले में सरल है: createDestinationInstancesForSourceInstance:entityMapping:manager:error:
।
कार्यान्वयन इस तरह दिखेगा:
StepOneEntityMigrationPolicy.m
#import "StepOneEntityMigrationPolicy.h"
@implementation StepOneEntityMigrationPolicy
- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance
entityMapping:(NSEntityMapping *)mapping
manager:(NSMigrationManager *)manager
error:(NSError **)error
{
NSManagedObject *newObject =
[NSEntityDescription insertNewObjectForEntityForName:[mapping destinationEntityName]
inManagedObjectContext:[manager destinationContext]];
NSDate *date = [sInstance valueForKey:@"timeStamp"];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[newObject setValue:[dateFormatter stringFromDate:date] forKey:@"printedDate"];
[dateFormatter release];
[manager associateSourceInstance:sInstance withDestinationInstance:newObject forEntityMapping:mapping];
return YES;
}
अंतिम चरण: माइग्रेशन ही
मैं दूसरे मैपिंग मॉडल को स्थापित करने के लिए भाग को छोड़ दूंगा जो लगभग समान है, बस एक बार InInvalvalSince1970 NSDate को एक डबल में परिवर्तित करने के लिए उपयोग किया जाता है।
अंत में हमें माइग्रेशन को ट्रिगर करना होगा। मैं अब के लिए बॉयलरप्लेट कोड छोड़ दूंगा। यदि आपको इसकी आवश्यकता है, तो मैं यहां पोस्ट करूंगा। यह माइग्रेशन प्रक्रिया को अनुकूलित करने पर पाया जा सकता है यह पहले दो कोड उदाहरणों का एक मर्ज है। तीसरे और अंतिम भाग के रूप में निम्नानुसार संशोधित किया जाएगा: के वर्ग विधि उपयोग करने के बजाय NSMappingModel
वर्ग mappingModelFromBundles:forSourceModel:destinationModel:
हम का उपयोग करेगा initWithContentsOfURL:
क्योंकि वर्ग विधि केवल एक ही है, शायद पहले पाया मानचित्रण बंडल में मॉडल वापस आ जाएगी।
अब हमें दो मैपिंग मॉडल मिल गए हैं जो लूप के हर पास में इस्तेमाल किए जा सकते हैं और माइग्रेट मैनेजर को माइग्रेट विधि भेज सकते हैं। बस।
NSArray *mappingModelNames = [NSArray arrayWithObjects:@"StepOne", @"StepTwo", nil];
NSDictionary *sourceStoreOptions = nil;
NSURL *destinationStoreURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataMigrationNew.sqlite"];
NSString *destinationStoreType = NSSQLiteStoreType;
NSDictionary *destinationStoreOptions = nil;
for (NSString *mappingModelName in mappingModelNames) {
NSURL *fileURL = [[NSBundle mainBundle] URLForResource:mappingModelName withExtension:@"cdm"];
NSMappingModel *mappingModel = [[NSMappingModel alloc] initWithContentsOfURL:fileURL];
BOOL ok = [migrationManager migrateStoreFromURL:sourceStoreURL
type:sourceStoreType
options:sourceStoreOptions
withMappingModel:mappingModel
toDestinationURL:destinationStoreURL
destinationType:destinationStoreType
destinationOptions:destinationStoreOptions
error:&error2];
[mappingModel release];
}
टिप्पणियाँ
cdm
बंडल में एक मैपिंग मॉडल समाप्त होता है ।
गंतव्य स्टोर प्रदान किया जाना चाहिए और स्रोत स्टोर नहीं होना चाहिए। आप सफल माइग्रेशन के बाद पुराने को हटा सकते हैं और नया नाम बदल सकते हैं।
मैंने मैपिंग मॉडल के निर्माण के बाद डेटा मॉडल में कुछ बदलाव किए, इसके परिणामस्वरूप कुछ संगतता त्रुटियां हुईं, जिन्हें मैं केवल मैपिंग मॉडल को फिर से बनाने के साथ हल कर सकता था।