मैं पूरे दिन के लिए "स्रोत स्टोर के लिए मॉडल नहीं ढूंढ सकता" पर अपने बालों को फाड़ रहा था।
आपका SQLite डेटाबेस के मॉडल हैश चाहिए माँ से एक से मेल करने या अपने xcdatamodel द्वारा बनाई momd जैसे ही आप ऐप्लिकेशन का निर्माण: यहाँ Googler के लिए learner2010 के जवाब का एक विस्तार है। आप निर्मित ऐप के बंडल में momd के VersionInfo.plist में हैंश देख सकते हैं। अपने डेटाबेस के मॉडल हैश को खोजने के लिए कोड के लिए नीचे देखें।
तो यदि आप एक्सकोड-> संपादक-> मॉडल संस्करण जोड़ें के तहत एक नया संस्करण बनाने के बजाय अपना xcdatamodel बदलते हैं ... तो आपके मॉडल का हैश अलग होगा, और addPersistentStoreWithType आपके पुराने डेटाबेस का उपयोग करने में सक्षम नहीं होगा , जो पुराने मॉडल का इस्तेमाल किया। यही कारण है कि "स्रोत स्टोर के लिए मॉडल नहीं मिल सकता" त्रुटि।
मामलों को और भी खराब बनाने के लिए, एसक्लाइट डेटाबेस "/ private/var/mobile/library/मोबाइल दस्तावेज़/YOU_APP_ID/Data.nosync/YOUR_DB.sqlite" जैसे कुछ में संग्रहीत किया जाता है और यह आपके द्वारा हटाए जाने पर भी टिक सकता है डिवाइस से ऐप और इसे पुनः स्थापित करें! तो आपको लगता है कि आपके कोड में कुछ गड़बड़ है, जब वास्तव में आपके पास एक पुराना डेटाबेस है जिसे हटाया जाना चाहिए।आमतौर पर यह डिबगिंग के दौरान होता है इसलिए वैसे भी इसमें कोई वास्तविक डेटा नहीं है।
तो भविष्य में माइग्रेशन की अनुमति देने के लिए उचित वर्कफ़्लो आपके मॉडल को बनाना, डेटाबेस बनाने के लिए अपना ऐप चलाएं, और उसके बाद किसी भी समय परिवर्तन करने की आवश्यकता वाले मॉडल के नए संस्करण बनाएं। यदि आप परिवर्तनों को मामूली रखते हैं तो सब कुछ "बस काम करेगा"। फिर, जब आप अपना ऐप रिलीज करने के लिए तैयार हों, तो अंतिम मॉडल का चयन करें और बाकी को हटाएं। फिर "/ private/var/मोबाइल/लाइब्रेरी/मोबाइल दस्तावेज़" से अपना डेटाबेस हटाएं। फिर भावी रिलीज पर, अपने नवीनतम मॉडल (यदि यह बदल गया है) के साथ पिछले रिलीज के सभी मॉडलों को शामिल करें और उपयोगकर्ता हर बार माइग्रेट करने में सक्षम होंगे।
यहाँ अब तक मेरी कोड है। महत्वपूर्ण पंक्ति यह है:
[fileManager removeItemAtPath:iCloudData error:&error];
लेकिन इसका उपयोग केवल आपके पुराने डेटाबेस को हटाने के लिए डिबगिंग के दौरान किया जाना है।
- (NSManagedObjectModel *)managedObjectModel
{
if (__managedObjectModel != nil)
{
return __managedObjectModel;
}
//NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"];
//__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
//NSArray *testArray = [[NSBundle mainBundle] URLsForResourcesWithExtension:@"momd"subdirectory:nil];
NSString *path = [[NSBundle mainBundle] pathForResource:@"Model" ofType:@"momd"];
if(!path) path = [[NSBundle mainBundle] pathForResource:@"Model" ofType:@"mom"];
NSURL *modelURL = [NSURL fileURLWithPath:path];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
//__managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
return __managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if((__persistentStoreCoordinator != nil)) {
return __persistentStoreCoordinator;
}
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
NSPersistentStoreCoordinator *psc = __persistentStoreCoordinator;
// Set up iCloud in another thread:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// ** Note: if you adapt this code for your own use, you MUST change this variable:
NSString *iCloudEnabledAppID = @"RW6RS7HS69.com.zsculpt.soaktest";
// ** Note: if you adapt this code for your own use, you should change this variable:
NSString *dataFileName = @"mydailysoak.sqlite";
// ** Note: For basic usage you shouldn't need to change anything else
NSString *iCloudDataDirectoryName = @"Data.nosync";
NSString *iCloudLogsDirectoryName = @"Logs";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *localStore = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:dataFileName];
NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];
if (iCloud) {
NSLog(@"iCloud is working");
NSURL *iCloudLogsPath = [NSURL fileURLWithPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]];
NSLog(@"iCloudEnabledAppID = %@",iCloudEnabledAppID);
NSLog(@"dataFileName = %@", dataFileName);
NSLog(@"iCloudDataDirectoryName = %@", iCloudDataDirectoryName);
NSLog(@"iCloudLogsDirectoryName = %@", iCloudLogsDirectoryName);
NSLog(@"iCloud = %@", iCloud);
NSLog(@"iCloudLogsPath = %@", iCloudLogsPath);
if([fileManager fileExistsAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]] == NO) {
NSError *fileSystemError;
[fileManager createDirectoryAtPath:[[iCloud path] stringByAppendingPathComponent:iCloudDataDirectoryName]
withIntermediateDirectories:YES
attributes:nil
error:&fileSystemError];
if(fileSystemError != nil) {
NSLog(@"Error creating database directory %@", fileSystemError);
}
}
NSString *iCloudData = [[[iCloud path]
stringByAppendingPathComponent:iCloudDataDirectoryName]
stringByAppendingPathComponent:dataFileName];
NSLog(@"iCloudData = %@", iCloudData);
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
[options setObject:iCloudEnabledAppID forKey:NSPersistentStoreUbiquitousContentNameKey];
[options setObject:iCloudLogsPath forKey:NSPersistentStoreUbiquitousContentURLKey];
[psc lock];
NSError *error;
[psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[NSURL fileURLWithPath:iCloudData]
options:options
error:&error];
if(error)
{
NSLog(@"Error adding persistent store %@, %@", error, [error userInfo]);
// comment in this line while debugging if get "Can't find model for source store" error in addPersistentStoreWithType.
// it means the sqlite database doesn't match the new model and needs to be created from scratch.
// this happens if you change the xcdatamodel instead of creating a new one under Xcode->Editor->Add Model Version...
// CoreData can only automatically migrate if there is a new model version (it can't migrate if the model simply changes, because it can't see the difference between the two models).
// be sure to back up the database if needed, because all data will be lost.
//[fileManager removeItemAtPath:iCloudData error:&error];
/*// this is another way to verify the hashes for the database's model to make sure they match one of the entries in the momd directory's VersionInfo.plist
NSDictionary *sourceMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:[NSURL fileURLWithPath:iCloudData] error:&error];
if(!sourceMetadata)
NSLog(@"sourceMetadata is nil");
else
NSLog(@"sourceMetadata is %@", sourceMetadata);*/
}
[psc unlock];
}
else {
NSLog(@"iCloud is NOT working - using a local store");
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
[psc lock];
NSError *error;
[psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:localStore
options:options
error:nil];
if(error)
NSLog(@"Error adding persistent store %@, %@", error, [error userInfo]);
[psc unlock];
}
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"SomethingChanged" object:self userInfo:nil];
});
});
return __persistentStoreCoordinator;
}
स्रोत
2012-09-06 22:59:00
तुम बस फोन के लिए एप्लिकेशन हटा सकते हैं और फिर से स्थापित है और आप एक नए सिरे से ऐप्स प्राप्त करने और इस प्रकार एक ताजा SQLite दुकान – thelaws