Если это был V3 модели данных, вам также необходимо включить в поставляемое приложение V1 и V2 xcdatamodel на тот случай, если некоторые из ваших пользователей все еще находятся на V1 и никогда не обновляются до V2. Похоже, у вас была модель данных V1, но вы ее не включили - но я не уверен, что вы можете просто говорить о других приложениях, где вы это сделали.
Кроме того, вы заметите, что XCode не управляет упорядоченным списком моделей данных, вы можете только выбрать, какая из них является текущей. Он не может автоматически обновить V1 -> ...-> Vm-> Vn, потому что он ничего не знает о порядке между старыми версиями, просто им нужно стать Vn для работы. Попробуйте покопаться в пакете xcdatamodeld с помощью текстового редактора.
Если вы полагаетесь исключительно на поведение, предоставляемое Core Data, все ваши предыдущие версии должны иметь возможность прямого перехода к последним версиям, будь то предполагаемые модели отображения или вы, включая модели явного отображения: из V1-> Vn, V2-> Vn, ..., Vm-> Vn. Вот почему некоторые люди пишут свой собственный код для управления этим.
Полагаю, это именно то, что Скотт описал в своем ответе.
Во время разработки нашего приложения мы создали ~ 6 версий модели данных (перед отправкой v1 в App Store мы взяли все, кроме самой последней версии). Мне показалось очень полезным написать модульные тесты, которые подтвердили, что Core Data может создать предполагаемую модель отображения и что облегченная миграция будет работать.
Для этого:
NSURL *sourceURL = /* exercise for reader */, *destinationURL = /* exercise */;
NSManagedObjectModel *source = [[NSManagedObjectModel alloc] initWithContentsOfURL:sourceURL];
NSManagedObjectModel *destination = [[NSManagedObjectModel alloc] initWithContentsOfURL:sourceURL];
NSError *mappingError;
NSMappingModel *inferred = [NSMappingModel inferredMappingModelForSourceModel:source destinationModel:destination error:&mappingError];
В конце этого блока кода вы можете утверждать, что выведено! = Nil, а если оно равно nil, вы можете распечатать некоторую полезную информацию, проверив mappingError.
Вы можете найти это полезным для устранения вашей проблемы. Вы можете переместить повторяющиеся части в функцию, которая принимает две строки: имя файла старой модели данных и имя файла последней.