मेरे पास एक बड़े, प्रीलोड किए गए डेटाबेस और एक छोटे उपयोगकर्ता डेटाबेस (कोरडाटा SQLite स्टोर्स दोनों) के साथ एक आईओएस प्रोजेक्ट है। पिछले प्रश्नों ने कॉन्फ़िगरेशन का उपयोग करके सुझाव दिया है कि कौन सी इकाइयों का उपयोग किस स्टोर के साथ किया जाता है। मुझे काम करने में परेशानी हो रही है। यहाँ मैं क्या कोशिश कर रहा है ... हैएकाधिक स्टोर्स के साथ कोरडाटा: कॉन्फ़िगरेशन woes
- (NSManagedObjectModel *)managedObjectModel
{
if (_managedObjectModel != nil) return _managedObjectModel;
// set up the model for the preloaded data
NSURL *itemURL = [[NSBundle mainBundle] URLForResource:@"FlagDB" withExtension:@"momd"];
NSManagedObjectModel *itemModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:itemURL];
// set up the model for the user data
NSURL *userDataURL = [[NSBundle mainBundle] URLForResource:@"UserData" withExtension:@"momd"];
NSManagedObjectModel *userDataModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:userDataURL];
// merge the models
_managedObjectModel = [NSManagedObjectModel modelByMergingModels:[NSArray arrayWithObjects:itemModel, userDataModel, nil]];
// define configurations based on what was in each model
WRONG [_managedObjectModel setEntities:itemModel.entities forConfiguration:@"ItemData"];
WRONG [_managedObjectModel setEntities:userDataModel.entities forConfiguration:@"UserData"];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) return _persistentStoreCoordinator;
// preloaded data is inside the bundle
NSURL *itemURL = [[[NSBundle mainBundle] bundleURL] URLByAppendingPathComponent:@"FlagDB.sqlite"];
// user data is in the application directory
NSURL *userDataURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"UserData.sqlite"];
NSManagedObjectModel *mom = self.managedObjectModel;
NSError *error = nil;
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:@"ItemData" URL:itemURL options:nil error:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
...
इस के साथ "दुकान खोलने के लिए किया मॉडल की दुकान बनाने के लिए इस्तेमाल एक के साथ असंगत है" aborts। दुकान में हैश के खिलाफ मॉडल में हैश की जांच से पता चलता है कि वे आइटमडेटा कॉन्फ़िगरेशन में मौजूद इकाइयों के समान हैं।
अगर मैं ऐसा तरह एक हल्के प्रवास कर रही है, की कोशिश:
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:@"ItemData" URL:itemURL options:options error:&error])
यह NSInvalidArgumentException ', कारण के साथ विफल रहता है:'। 'ItemData' मॉडल विन्यास शामिल नहीं है ' मुझे लगता है कि ऐसा इसलिए है क्योंकि लाइटवेट माइग्रेशन प्रक्रिया द्वारा एक नया मॉडल बनाया जा रहा है, और इसमें मेरी कॉन्फ़िगरेशन नहीं है।
अन्य धागे में कुछ सुझावों के आधार पर, मैंने कॉन्फ़िगरेशन के बिना हल्के माइग्रेशन करने का प्रयास किया है, और फिर कॉन्फ़िगरेशन का उपयोग करके एक नया समन्वयक बना रहा है। इस प्रकार के काम, लेकिन यह उपयोगकर्ता डेटा इकाइयों (जो वहां से संबंधित नहीं है) से संबंधित मेरी प्रीलोडेड .sqlite फ़ाइल में तालिकाओं को जोड़ता है, और नव निर्मित उपयोगकर्ता डेटा स्टोर में प्रीलोड किए गए डेटा टेबल और उपयोगकर्ता डेटा टेबल दोनों बनाता है । अंत परिणाम यह है कि असफल हो जाते हैं, प्रतीत होता है क्योंकि वे गलत स्टोर में देख रहे हैं।
NSDictionary *migrationOptions = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
// make a temp persistent store coordinator to handle the migration
NSPersistentStoreCoordinator *tempPsc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
// migrate the stores
if (![tempPsc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:itemURL options:migrationOptions error:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
if (![tempPsc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:userDataURL options:migrationOptions error:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
// make a permanent store coordinator
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
NSDictionary *readOnlyOptions = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSReadOnlyPersistentStoreOption, nil];
if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:@"ItemData" URL:itemURL options:readOnlyOptions error:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
/*if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:@"UserData" URL:userDataURL options:nil error:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}*/
और फिर बाद में ...
OSAppDelegate *delegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = delegate.managedObjectContext;
// sanity check
for (NSPersistentStore *store in context.persistentStoreCoordinator.persistentStores) {
NSLog(@"store %@ -> %@", store.configurationName, store.URL);
NSMutableArray *entityNames = [[NSMutableArray alloc] init];
for (NSEntityDescription *entity in [context.persistentStoreCoordinator.managedObjectModel entitiesForConfiguration:store.configurationName]) {
[entityNames addObject:entity.name];
}
NSLog(@"entities: %@", entityNames);
}
NSFetchRequest *categoryFetchRequest = [[NSFetchRequest alloc] init];
categoryFetchRequest.entity = [NSEntityDescription entityForName:@"Category" inManagedObjectContext:context];
categoryFetchRequest.predicate = [NSPredicate predicateWithFormat:@"name == %@", categoryName];
NSError *error = nil;
Category *category = [[delegate.managedObjectContext executeFetchRequest:categoryFetchRequest error:&error] lastObject];
यह ठीक काम करता है, उचित नाम श्रेणी वस्तु लौटने, जब तक मैं दूसरे की दुकान के अलावा uncomment। अगर मैं ऐसा करता हूं, तो fetch परिणाम वापस खाली आता है। डायग्नोस्टिक एनएसएलओजी संदेश वास्तव में प्रिंट करते हैं जो मैं अपेक्षा करता हूं। प्रत्येक स्टोर सही विन्यास से जुड़ा हुआ है, और प्रत्येक कॉन्फ़िगरेशन में उपयुक्त इकाइयां हैं।
क्या कोई मुझे एक काम करने वाले एकाधिक स्टोर सेटअप के लिए स्रोत कोड पर इंगित कर सकता है, या मुझे गलत करने के लिए मुझे बता सकता है? अग्रिम में धन्यवाद!
हल: समस्या की जड़ दो पंक्तियों पहले कोड सूची में गलत चिह्नित किया गया था। मैं प्रोग्रामेटिक रूप से कॉन्फ़िगरेशन बनाने का प्रयास कर रहा था, लेकिन यह अपर्याप्त प्रतीत होता है। यदि आप ऐसा करने के बाद कॉन्फ़िगरेशन के लिए ManagedObjectModel से पूछताछ करते हैं, तो आप वास्तव में सूची में कॉन्फ़िगरेशन देखते हैं, और सही इकाइयां उन कॉन्फ़िगरेशन से जुड़ी हैं। हालांकि, ऐसा लगता है कि PersistentStoreCoordinator को ठीक से उपयोग करने में सक्षम बनाने के लिए कुछ और करने की आवश्यकता है। एक्सकोड में कॉन्फ़िगरेशन बनाना उन्हें काम करता है।
यूपी का पालन करें: वहाँ एक अतिरिक्त रोड़ा है। अंतिम पर्सिस्टेंट स्टोर कोऑर्डिनेटर सेट करने से पहले एक अलग माइग्रेशन पास चलाने का समाधान सिम्युलेटर में बहुत अच्छा काम करता है। एक वास्तविक डिवाइस पर, अनुमतियां कठोर हैं। यदि आप उस माइग्रेशन को करने का प्रयास करते हैं, तो यह विफल हो जाता है क्योंकि ऐप बंडल में स्टोर केवल पढ़ने के लिए है। प्रवास तब तक जरूरी प्रतीत होता है जब तक आप अपने मॉडल को समेकित नहीं करते। यदि आपके पास केवल एक मॉडल है, और ऐप बंडल में स्टोर इसके साथ संगत है, तो माइग्रेशन आवश्यक नहीं है और एक्सकोड कार्यों में परिभाषित कॉन्फ़िगरेशन का उपयोग करके एक्सेस नहीं है।
माइग्रेशन का प्रयास करने से पहले डेटा को दस्तावेज़ निर्देशिका में स्थानांतरित करने का एक और विकल्प हो सकता है। मैंने सत्यापित नहीं किया है कि वह दृष्टिकोण काम करता है।
सुनिश्चित करें कि आप ऐप सैंडबॉक्स की उपयोगकर्ता दस्तावेज़ निर्देशिका पर माइग्रेशन कर रहे हैं - जिसे पढ़ा/लिखना है - और ऐप बंडल में नहीं। – Sunny
मैं डेटा को दस्तावेज़ निर्देशिका में स्थानांतरित नहीं करना चाहता था क्योंकि मैं नहीं चाहता कि (स्थैतिक) डेटा का बैकअप लिया जाए और उपयोगकर्ता के iCloud कोटा के विरुद्ध गिना जाए। लेकिन यह आईओएस 5.0.1 में लगता है जैसे बैक अप लेने के लिए फ़ाइलों को नामित करने का एक तरीका है: http://developer.apple.com/library/ios/#qa/qa1719/_index.html – Aneel
ठीक है, आपने मुझे प्रेरित किया और मेरी समस्या को हल करने के लिए कुछ घंटों खर्च करने के बाद, मैंने इस पर एक पूरा लेख लिखा [यहां] (http://blog.atwam.com/blog/2012/05/11/multiple-persist-stores-and-seed-data -साथ कोर-डेटा /)। मुझे लगा कि यह भविष्य में कुछ अन्य लोगों की मदद कर सकता है। – Wam