Модель, используемая для открытия магазина, несовместима с моделью, используемой для создания магазина. - PullRequest
179 голосов
/ 16 января 2012

Я создал модель базовых данных в xcode 3.2, а после обновления в Xcode 4.2 я добавил новую сущность подкласса NSManagedObject (см. Новую сущность).

Во-первых, это выглядит странно, потому что он не в той же группе, что и старая. Вот изображение на моем xcode 4.2 (AlkitabDB - это то, что я создал в xcode 3.2, EndeDB - новое из текущей версии xcode (4.2):

the new entity do not grouped in xdatamodel

Во-вторых, я оставил все как есть, затем я получил доступ ко второй сущности (новой) так же, как и к первой сущности (старой), и появляется ошибка с названием.

Вот ошибка:

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";
}

Ранее я искал решение и обнаружил, что должен удалить приложение из симулятора и повторно запустить приложение, и оно не сработало. Кто-нибудь знает решение этой проблемы? Пожалуйста, помогите.

Ответы [ 25 ]

283 голосов
/ 16 января 2012

Удалите приложение из симулятора и выполните очистку вашего проекта. Это должно прояснить эти проблемы. Убедитесь, что вы не работаете в отладчике при удалении приложения, иначе оно не удастся удалить должным образом.

Если вы хотите быть уверенным, что он исчез, проверьте этот каталог Users/INSERT_YOUR_USER_HERE/Library/Application Support/iPhone Simulator/ на наличие папки вашего приложения в версии, которую вы используете.

Примечание: это только для разработки. Для производства вам нужно реализовать какую-то миграцию. Google "Core Data Migration", с упрощенной миграцией, являющейся самой простой.

282 голосов
/ 04 июля 2013

Иногда удаление приложения происходит не так! Предложите, ваше приложение уже опубликовано! Вы не можете просто добавить новый объект в базу данных и продолжить - вам нужно выполнить миграцию!

Для тех, кто не хочет копаться в документации и ищет быстрое решение:

  1. Откройте файл .xcdatamodeld
  2. нажмите на редактор
  3. выберите Добавить версию модели ...
  4. Добавить новую версию вашей модели (добавлена ​​новая группа моделей данных)
  5. выбрать основной файл, открыть инспектор файлов (правая панель)
  6. и под Versioned core data model выберите новую версию модели данных для текущей модели данных
  7. ЭТО НЕ ВСЕ) Вы должны выполнить так называемую «легкую миграцию».
  8. Перейдите к вашему AppDelegate и найдите, где создается persistentStoreCoordinator
  9. Найти эту строку if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
  10. Заменить nil опции на @{NSMigratePersistentStoresAutomaticallyOption:@YES, NSInferMappingModelAutomaticallyOption:@YES} (фактически предоставлено в закомментированном коде в этом методе)
  11. Вот, пожалуйста, веселитесь!

P.S. Это относится только к облегченной миграции. Чтобы ваша миграция квалифицировалась как легкая миграция, ваши изменения должны быть ограничены к этой узкой полосе:

  • Добавление или удаление свойства (атрибута или отношения).
  • Сделать необязательное свойство необязательным.
  • Сделать необязательный атрибут неопциональным, если вы укажете значение по умолчанию.
  • Добавить или удалить объект.
  • Переименовать недвижимость.
  • Переименование сущности.

Для Swift 4

coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true])
33 голосов
/ 24 апреля 2014

Просто добавьте атрибут Опции при создании persistentStoreCoordinator в файле AppDelegate.m для метода основных данных, как показано ниже

Objective-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
}

Это решило мою проблему ..

23 голосов
/ 25 мая 2013

Ответ: Удалите приложение из симулятора, выполните очистку и перестройте свой проект.

Примечание: При каждом изменении основных данныхопределение, удалите приложение, установленное на физическом устройстве или симуляторе, очистите проект и заново выполните сборку.

14 голосов
/ 24 мая 2016

Для swift в 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])
14 голосов
/ 30 июля 2012

Да.Как только вы удалите приложение на физическом устройстве и восстановите его, оно заработает.

11 голосов
/ 31 октября 2012

Я только что провел несколько дней, борясь с этой ошибкой, а также с ошибками 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 из thisпоэтому вопрос : чтобы помочь выяснить это, зарегистрировав все файлы .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];
10 голосов
/ 11 июля 2012

Каждый раз, когда вы вносите изменения в определение базовой даты, вы должны удалять приложения, установленные на физическом устройстве или симуляторе.

9 голосов
/ 19 мая 2015
  1. Остановить запуск приложения.
  2. Удалить приложение на симуляторе.
  3. Product -> Clean
  4. Сборка, запуск.
7 голосов
/ 12 января 2016

Самое простое решение, которое сработало для меня в Swift 2.1, Xcode 7:

  1. Удалите приложение из симулятора (Cmd + Shift + H, чтобы перейти на главный экран. LongНажмите приложение, нажмите крестик, просто обычным способом удаления приложения из телефона)

  2. Cmd + Shift + H еще раз, чтобы остановить танец приложений

  3. Вернитесь к своему проекту и повторно запустите

У меня была эта проблема при записи / чтении из Core Data с двумя настроенными сущностями.Удаление приложения и повторный запуск программы устранили проблему

...