Я лично не использовал CoreData, поэтому понятия не имею, есть ли у него специальные инструменты для обработки этого.Но в целом да, вам необходимо создавать и хранить сценарии SQL, которые будут мигрировать из каждой версии вашего приложения в следующую.
Когда приложение установлено, оно должно проверить текущую версию модели данных на соответствиеверсия модели данных, используемой приложением.Должен быть «дельта-скрипт» для перехода от каждой версии к каждой следующей версии.Затем следует применить каждую дельту, необходимую для перехода от текущей модели к необходимой модели.
Например, если вы отправили 4 версии в AppStore.Вам необходим дельта-скрипт для перехода с версии 1 на 2, с 2 на 3 и с 3 на 4.
Каждый раз, когда приложение запускается, оно проверяет текущую версию модели данных на соответствие требуемой версии исполняемого файла.Если, например, версия 4 установлена на устройстве, но пользователь никогда не устанавливал версию 3, приложение запустится.Проверьте текущую версию модели, которая равна 2. Сравните ее с версией исполняемого файла, равной 4. Затем примените сценарий 2–3, а затем сценарий 3–4.
Сам номер версии может бытьхранятся в базе данных и должны увеличиваться после применения дельт, либо из самих дельт, либо автоматически в коде обработки.
Дельты могут храниться либо в виде константных строк в ваших файлах кода, либо просто как файлы ресурсов вваш проект.
Редактировать: (вот мой код миграции)
+ (NSArray*) chop:(NSString*)sql {
NSMutableArray* list = [[NSMutableArray alloc] init];
NSMutableString* sb = [[NSMutableString alloc] init];
BOOL inside = FALSE;
for (int i=0;i<[sql length];i++) {
if ([sql characterAtIndex:i] == '\n') continue;
if ([sql characterAtIndex:i] == '\r') continue;
[sb appendFormat:@"%c",[sql characterAtIndex:i]];
if (!inside) {
if ([sql characterAtIndex:i] == '\'')
inside = TRUE;
else if ([sql characterAtIndex:i] == ';') {
[sb deleteCharactersInRange:NSMakeRange([sb length]-1,1)];
[list addObject:sb];
[sb release];
sb = [[NSMutableString alloc] init];
}
} else {
if ([sql characterAtIndex:i] == '\'')
inside = FALSE;
else if ([sql characterAtIndex:i] == '\\') {
i++;
[sb appendFormat:@"%c",[sql characterAtIndex:i]];
}
}
}
[sb release];
return [list autorelease];
}
+ (void) updateObjectModel {
[Log output:@"[migration]"];
int version;
@try {
int exist = [SQL queryLong:@"SELECT COUNT(*) FROM Variables WHERE Key='objectModelVersion'"];
if (exist)
version = [SQL retrieveInt:@"objectModelVersion"]+1;
else {
[Log output:@"[bootstrapping]"];
[SQL storeInt:@"objectModelVersion" as:1];
version = 2;
}
} @catch (NSException* e) {
[Log output:@"[initializing]"];
version = 0;
}
while (TRUE) {
NSString* filename = [NSString stringWithFormat:@"SQLite-%04d",version];
NSString* file = [[NSBundle mainBundle] pathForResource:filename ofType:@"sql"];
if (file) {
[Log output:[NSString stringWithFormat:@"[%d]",version]];
NSArray* commands = [SQL chop:[NSString stringWithContentsOfFile:file encoding:NSASCIIStringEncoding error:NULL]];
for (NSString* command in commands)
[SQL update:command];
[SQL storeInt:@"objectModelVersion" as:version];
} else break;
version++;
}
[Log output:@"[/migration]\n"];
}