Модель, используемая для открытия магазина, несовместима с моделью, используемой для создания магазина.
Я создал модель Core Data в xcode 3.2 и после обновления в Xcode 4.2 я добавил новую сущность подкласса NSManagedObject (см. Новую сущность).
Во-первых, это выглядит странно, потому что он не в той же группе, что и старая. Вот изображение на моем xcode 4.2 (AlkitabDB - это то, что я создал в xcode 3.2, EndeDB - это новое из текущей версии xcode (4.2):
Во-вторых, я оставил все как есть, затем я получил доступ ко второй сущности (новой) так же, как и к первой сущности (старой), и появляется ошибка с названием.
Вот ошибка:
2012-01-16 21:13:38.496 iHuria[55953:207] Unresolved error Error Domain=NSCocoaErrorDomain Code=134100 "The operation couldn’t be completed. (Cocoa error 134100.)" UserInfo=0x8829cd0 {metadata=<CFBasicHash 0x882a370 [0x1839b38]>{type = immutable dict, count = 7,
entries =>
2 : <CFString 0x8829b90 [0x1839b38]>{contents = "NSStoreModelVersionIdentifiers"} = <CFArray 0x8829ff0 [0x1839b38]>{type = immutable, count = 0, values = ()}
4 : <CFString 0x8829bc0 [0x1839b38]>{contents = "NSPersistenceFrameworkVersion"} = <CFNumber 0x8829770 [0x1839b38]>{value = +320, type = kCFNumberSInt64Type}
6 : <CFString 0x8829bf0 [0x1839b38]>{contents = "NSStoreModelVersionHashes"} = <CFBasicHash 0x882a080 [0x1839b38]>{type = immutable dict, count = 1,
entries =>
0 : <CFString 0x882a010 [0x1839b38]>{contents = "AlkitabDB"} = <CFData 0x882a030 [0x1839b38]>{length = 32, capacity = 32, bytes = 0xd02ac5f8be6ab0b39add450aca202ac0 ... 3d45d462998d2ccd}
}
7 : <CFString 0x10e3aa8 [0x1839b38]>{contents = "NSStoreUUID"} = <CFString 0x8829e60 [0x1839b38]>{contents = "4F2EE7FF-463B-4055-BBED-8E603CDBDF59"}
8 : <CFString 0x10e3948 [0x1839b38]>{contents = "NSStoreType"} = <CFString 0x10e3958 [0x1839b38]>{contents = "SQLite"}
9 : <CFString 0x8829c40 [0x1839b38]>{contents = "NSStoreModelVersionHashesVersion"} = <CFNumber 0x6b1c7c0 [0x1839b38]>{value = +3, type = kCFNumberSInt32Type}
10 : <CFString 0x8829c70 [0x1839b38]>{contents = "_NSAutoVacuumLevel"} = <CFString 0x882a0c0 [0x1839b38]>{contents = "2"}
}
, reason=The model used to open the store is incompatible with the one used to create the store}, {
metadata = {
NSPersistenceFrameworkVersion = 320;
NSStoreModelVersionHashes = {
AlkitabDB = <d02ac5f8 be6ab0b3 9add450a ca202ac0 ebd1e860 cbb578c2 3d45d462 998d2ccd>;
};
NSStoreModelVersionHashesVersion = 3;
NSStoreModelVersionIdentifiers = (
);
NSStoreType = SQLite;
NSStoreUUID = "4F2EE7FF-463B-4055-BBED-8E603CDBDF59";
"_NSAutoVacuumLevel" = 2;
};
reason = "The model used to open the store is incompatible with the one used to create the store";
}
Я искал решение раньше и обнаружил, что я должен удалить приложение из симулятора и повторно запустить приложение, и оно не работает. Кто-нибудь знает решение этой проблемы? Пожалуйста помоги.
27 ответов
Удаление приложения иногда не так! Предложите, ваше приложение уже опубликовано! Вы не можете просто добавить новый объект в базу данных и продолжить - вам нужно выполнить миграцию!
Для тех, кто не хочет копаться в документации и ищет быстрое решение:
- Откройте ваш файл.xcdatamodeld
- нажмите на редактор
- выберите Добавить версию модели...
- Добавьте новую версию вашей модели (добавлена новая группа моделей данных)
- выберите основной файл, откройте инспектор файлов (правая панель)
- и под
Versioned core data model
выберите новую версию модели данных для текущей модели данных - Это не все) Вы должны выполнить так называемую "легкую миграцию".
- Перейти к вашей
AppDelegate
и найти гдеpersistentStoreCoordinator
создается - Найти эту строку
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
- замещать
nil
варианты с@{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES}
(фактически предоставлено в закомментированном коде в этом методе) - Вот, пожалуйста, веселитесь!
PS Это касается только облегченной миграции. Чтобы ваша миграция квалифицировалась как легкая миграция, ваши изменения должны быть ограничены этой узкой полосой:
- Добавить или удалить свойство (атрибут или отношение).
- Сделать необязательное свойство необязательным.
- Сделайте необязательный атрибут необязательным, если вы укажете значение по умолчанию.
- Добавить или удалить объект.
- Переименовать собственность.
- Переименуйте объект.
Для Swift 4
coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true])
Удалите приложение из симулятора и выполните очистку вашего проекта. Это должно прояснить эти проблемы. Убедитесь, что вы не работаете в отладчике при удалении приложения, иначе оно на самом деле не удалится должным образом.
Если вы хотите быть уверенным, что его нет, проверьте этот каталог Users/INSERT_YOUR_USER_HERE/Library/Application Support/iPhone Simulator/
для папки вашего приложения, под версией, которую вы используете.
Примечание: это только для разработки. Для производства вам необходимо реализовать какую-то миграцию. Google "Core Data Migration", с упрощенной миграцией, являющейся самой простой.
Просто добавьте атрибут Options при создании persistentStoreCoordinator в файле AppDelegate.m для метода основных данных, как показано ниже
Obje ctive-C
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil)
{
return _persistentStoreCoordinator;
}
NSLog(@"persistentStoreCoordinator___");
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"MyApp.sqlite"];
NSMutableDictionary *options = [[NSMutableDictionary alloc] init];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
NSLog(@"persistentStoreCoordinator___2");
return _persistentStoreCoordinator;
}
СВИФТ
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
var failureReason = "There was an error creating or loading the application's saved data."
// MAIN LINE OF CODE TO ADD
let mOptions = [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
do {
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: mOptions)
} catch {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
abort()
}
return coordinator
}
Это решило мою проблему..
Ответ: удалите приложение из симулятора, выполните очистку и перестройте свой проект.
Примечание. Всякий раз, когда вы вносите изменения в определение базовых данных, удалите приложение, установленное на физическом устройстве или в симуляторе, очистите проект и заново выполните сборку.
Для быстрого, в AppDelegate.swift найдите строку
try coordinator!.addPersistentStoreWithType(NSXMLStoreType, configuration: nil, URL: url, options: nil )
и заменить его на
try coordinator!.addPersistentStoreWithType(NSXMLStoreType, configuration: nil, URL: url, options: [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true])
Да. После того, как вы удалите приложение на физическом устройстве и восстановите его, оно заработает.
Я просто потратил несколько дней на борьбу с этой ошибкой, а также с ошибками mergedModelFromBundles и ошибкой "Не удается объединить модели с двумя разными сущностями с именем *".
Оказывается, основная проблема заключалась в том, что XCode не удаляет старые ресурсы с устройств, и у меня были старые версии моей модели данных (файлы.mom), которые вызывали конфликты. Вот почему удаление приложения устранило проблему на одном из моих устройств.
После нахождения этого поста в другом ответе SO я сделал свое приложение более терпимым к старым моделям, изменив эту строку, которая ищет ВСЕ файлы.mom:
NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
к этому, который смотрит только в каталоге Filters:
NSString *path = [[NSBundle mainBundle] pathForResource:@"Filters" ofType:@"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
Я использовал recursivePathsForResourcesOfType из этого вопроса, чтобы выяснить это, зарегистрировав все файлы.mom в приложении:
NSArray *momPaths = [self recursivePathsForResourcesOfType:@"mom" inDirectory:[[NSBundle mainBundle] resourcePath]];
NSLog(@"All .mom files:%@",momPaths);
Я также использовал iExplorer для просмотра посторонних файлов.mom (пока не пытался их удалить).
Метод ниже был также полезен. Это показало, что сущность была в объединенной модели, возвращенной [psc managedObjectModel], которой больше не существует ни в одной из моих моделей или в самом магазине. Это было то, что позволило мне полагать, что старая модель кэшировалась на самом устройстве, которое чистое здание не удаляло. Метод регистрирует каждый объект, который является таким же, был изменен, добавлен или удален из модели. (написано с таким ответом SO в качестве отправной точки):
- (BOOL)comparePersistentStore:(NSPersistentStoreCoordinator *)psc withStoreURL: (NSURL *)storeURL {
NSError *error = nil;
// Get the entities & keys from the persistent store coordinator
NSManagedObjectModel *pscModel = [psc managedObjectModel];
NSDictionary *pscEntities = [pscModel entitiesByName];
NSSet *pscKeys = [NSSet setWithArray:[pscEntities allKeys]];
//NSLog(@"psc model:%@", pscModel);
//NSLog(@"psc keys:%@", pscKeys);
NSLog(@"psc contains %d entities", [pscModel.entities count]);
// Get the entity hashes from the storeURL
NSDictionary *storeMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType
URL:storeURL
error:&error];
NSDictionary *storeHashes = [storeMetadata objectForKey:@"NSStoreModelVersionHashes"];
//NSLog(@"store metadata:%@", sourceMetadata);
NSLog(@"store URL:%@", storeURL);
NSLog(@"store NSStoreUUID:%@", [storeMetadata objectForKey:@"NSStoreUUID"]);
NSLog(@"store NSStoreType:%@", [storeMetadata objectForKey:@"NSStoreType"]);
NSSet *storeKeys = [NSSet setWithArray:[storeHashes allKeys]];
// Determine store entities that were added, removed, and in common (to/with psc)
NSMutableSet *addedEntities = [NSMutableSet setWithSet:pscKeys];
NSMutableSet *removedEntities = [NSMutableSet setWithSet:storeKeys];
NSMutableSet *commonEntities = [NSMutableSet setWithSet:pscKeys];
NSMutableSet *changedEntities = [NSMutableSet new];
[addedEntities minusSet:storeKeys];
[removedEntities minusSet:pscKeys];
[commonEntities minusSet:removedEntities];
[commonEntities minusSet:addedEntities];
// Determine entities that have changed (with different hashes)
[commonEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) {
NSData *storeHash = [storeHashes objectForKey:key];
NSEntityDescription *pscDescrip = [pscEntities objectForKey:key];
if ( ! [pscDescrip.versionHash isEqualToData:storeHash]) {
if (storeHash != nil && pscDescrip.versionHash != nil) {
[changedEntities addObject:key];
}
}
}];
// Remove changed entities from common list
[commonEntities minusSet:changedEntities];
if ([commonEntities count] > 0) {
NSLog(@"Common entities:");
[commonEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) {
NSData *storeHash = [storeHashes objectForKey:key];
NSEntityDescription *pscDescrip = [pscEntities objectForKey:key];
NSLog(@"\t%@:\t%@", key, pscDescrip.versionHash);
}];
}
if ([changedEntities count] > 0) {
NSLog(@"Changed entities:");
[changedEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) {
NSData *storeHash = [storeHashes objectForKey:key];
NSEntityDescription *pscDescrip = [pscEntities objectForKey:key];
NSLog(@"\tpsc %@:\t%@", key, pscDescrip.versionHash);
NSLog(@"\tstore %@:\t%@", key, storeHash);
}];
}
if ([addedEntities count] > 0) {
NSLog(@"Added entities to psc model (not in store):");
[addedEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) {
NSEntityDescription *pscDescrip = [pscEntities objectForKey:key];
NSLog(@"\t%@:\t%@", key, pscDescrip.versionHash);
}];
}
if ([removedEntities count] > 0) {
NSLog(@"Removed entities from psc model (exist in store):");
[removedEntities enumerateObjectsUsingBlock:^(NSString *key, BOOL *stop) {
NSData *storeHash = [storeHashes objectForKey:key];
NSLog(@"\t%@:\t%@", key, storeHash);
}];
}
BOOL pscCompatibile = [pscModel isConfiguration:nil compatibleWithStoreMetadata:storeMetadata];
NSLog(@"Migration needed? %@", pscCompatibile?@"no":@"yes");
return pscCompatibile;
}
использование: вызывается перед добавлением каждого хранилища в NSPersistentStoreCoordinator:
[self comparePersistentStore:self.psc withStoreURL:self.iCloudStoreURL];
_iCloudStore = [self.psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:self.iCloudStoreURL
options:options
error:&localError];
Каждый раз, когда вы вносите изменения в определение базовой даты, вы должны удалять приложения, установленные на физическом устройстве или симуляторе.
- Остановить запуск приложения.
- Удалить приложение на симуляторе.
Product
->Clean
- Построй, беги.
Самое простое решение, которое работало для меня в Swift 2.1, Xcode 7:
Удалите приложение из симулятора ( Ctrl + Shift + H, чтобы перейти на главный экран. Нажмите и удерживайте приложение, нажмите крестик, как обычно, чтобы удалить приложение с телефона).
Cmd + Shift + H снова, чтобы остановить танцы приложений
Вернитесь к своему проекту и повторите
У меня была эта проблема при записи / чтении из Core Data с двумя настроенными сущностями. Удаление приложения и повторный запуск программы устранили проблему
Я только что удалил [Simulator App Folder]/Document/*.sqlite
файл после внесения изменений в сущности и все заработало. И, конечно же, файл.sqlite содержит все сохраненные данные и структуры, которые будут потеряны.
Пожалуйста, удалите приложение из симулятора, очистите код и запустите.it работает нормально. Это может помочь вам.
Если вы используете Swift.
Следуйте ответу @Stas и вставьте параметры вместо nil в ваш делегат приложения:
let myOptions = [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: myOptions, error: &error) == nil {
Попробуйте "Сбросить содержимое и настройки" в симуляторе. Сработало у меня после удаления приложения и Чистой сборки
У меня возникла та же проблема с моим приложением (еще не выпущенным в App Store).
Вот как я это исправил:
- Run Clean (Cmd + Shift + K)
- Перезапустите iOS Симулятор
- Симулятор iOS -> Сбросить содержимое и настройки (из панели навигации)
(3) был шаг, который наконец заставил это бежать должным образом. Надеюсь это поможет!
В моем случае у меня было два постоянных хранилища, одно локальное хранилище для пользовательских данных и одно хранилище CoreData+CloudKit для общих данных, которые автоматически синхронизируются с iCloud. Таким образом, модель данных имеет две конфигурации, и сущности назначаются обеим конфигурациям по мере необходимости.
Из-за ошибки во время разработки я попытался сохранить объект, который больше не был связан ни с одной конфигурацией. Итак, когда контекст был сохранен, CoreData понял несовместимость и вылетел с этой ошибкой.
Конечно, удаление приложения в таком случае не поможет. Необходимо убедиться, что в постоянном хранилище хранятся только назначенные объекты.
Если вы вносите изменения в модель Core Data, вы должны предоставить политику миграции, которая сообщает Core Data, как перенести существующие постоянные объекты (созданные пользователями с текущей выпущенной версией) в новую модель.
Для некоторых сценариев Core Data может автоматически выводить отображение из старой модели в новую. Для более сложных изменений вам может потребоваться реализовать некоторую логику, которая выполняет миграцию.
Подробности можно найти в Руководстве по программированию версий базовой модели данных и миграции данных.
Обновить
Этот ответ здесь о переполнении стека охватывает основы облегченной миграции Core Data, а также содержит некоторый код для начала работы.
Во-первых, единственное, что должно быть в xcdatamodeld
расслоение xcdatamodel
файлы. Ваши подклассы НЕ должны быть в xcdatamodeld
, Переместите их оттуда. Есть большая вероятность, что они путают компилятор.
Во-вторых, ошибка указывает на то, что Core Data не может найти вашу модель. Вы создали данные и затем коснулись модели? Если это так, вы находитесь в несовместимом состоянии и должны исправить это, либо удалив данные (что предложил Филипп), либо откатив изменения модели НАЗАД.
Хотя иногда вы можете просто удалить приложение с устройства при изменении схемы в модели управляемых объектов, в некоторых случаях это невозможно, например, потому что вы уже опубликовали свое приложение со старой схемой.
Если это так, вы должны позаботиться о переносе старых данных в новую схему:
Вам нужно будет перенести модель Core Data с помощью миграции. Каждый раз, когда вы меняете модель, вы делаете ее несовместимой без контроля версий. Пристегнитесь, это немного волосатая тема.
Это может помочь некоторым людям, но не может ответить на вопрос. В моем случае проблема решилась тем, что я забыл добавить модель в правильную конфигурацию. Смотрите прикрепленный скриншот. Все модели добавляются в конфигурацию по умолчанию, но мое приложение использует частную конфигурацию. Перетащите модель из конфигурации по умолчанию в правильную конфигурацию.
Эта проблема обычно возникает из-за несовместимости версии, в которой была создана БД. Общий подход к этой проблеме - удалить приложение и переустановить его. Но в упомянутом вами случае версия БД полностью отличается на Xcode 3.2 и 4.2. Так что лучше использовать ту же версию Xcode для БД.
При изменении основных данных (добавление поля в таблицу, удаление поля и т. Д.) Файл sqlite в папке документов приложений должен синхронизироваться с вашей схемой.
Этот файл не перезаписывается по умолчанию, этот файл необходимо восстановить.
Следуй этим шагам:
Перейдите в папку, указанную NSURL. (Этот путь можно найти в сообщении об исключении, сгенерированном приложением перед сбоем.) Пример: / Пользователи // Библиотека / Поддержка приложений /iPhone Simulator// Приложения // Документы
удалить или переименовать файл sqlite
- Очистите и запустите приложение
- При повторном запуске приложения будет создан новый файл sqlite.
Это обеспечит синхронизацию схемы и Xcode.
У меня была эта проблема - я сначала перезагружаю симулятор, а затем очищаю проект и перестраиваю. И тогда это работает.
Я получаю ошибку, но причина, по которой я ее получаю, заключается в следующем.
Первоначально у меня был один объект с именем "Entry", и в базе данных была сохранена одна строка для этого объекта. Затем я добавил еще одну сущность с именем "Person" и после добавления пошел в сборку и получил ошибку. Поэтому я решил проблему, удалив сущность "Персона", а затем собрав приложение, удалив строку, находящуюся в "Записи", а затем закрыл приложение. Затем я полностью удалил приложение с телефона, а затем сделал восстановление, и оно работало нормально. Не уверен, какой шаг исправил проблему (удаление строки или приложения), но, надеюсь, если вы ищете решение, это поможет.:)
Изменить: Да, и если вы беспокоитесь об удалении вашей новой сущности (в моем случае "Персона") для повторной сборки приложения, помните, что вы можете получить ее позже, используя CMD+Z!
Для разработки приложений Mac:
- Очистить проект
- Очистить полученные данные
- Перейдите в /Users/YOUR_NAME/Library/Containers/YOUR_APP_BUNDLE_ID/Data/Documents/ и удалите все файлы внутри (например, ".sqlite", ".sqlite-shm"...)
Это сработало для меня, надеюсь, это могло бы быть полезным.
Симулятор iOS -> Сбросить содержимое и настройки...
Работал для меня
Симулятор iOS -> Сбросить содержимое и настройки... -> Сброс Работает также на iOS9 (xcode 7.1)