Je n'ai pas personnellement utilisé CoreData, donc je ne sais pas s'il a des outils spéciaux pour gérer cela. Mais, en général oui, vous devez créer et stocker des scripts SQL qui migreront de chaque version de votre application à la suivante. Lorsque l'application est installée, elle doit vérifier la version actuelle du modèle de données par rapport à la version du modèle de données utilisée par l'application. Il devrait y avoir un script "delta" pour passer de chaque version à chaque nouvelle version. Chacun des deltas nécessaires pour passer du modèle actuel au modèle nécessaire devrait alors être appliqué.
Par exemple, si vous avez envoyé 4 versions à l'AppStore. Chaque fois que l'application se lance, elle vérifie la version actuelle du modèle de données par rapport à la version souhaitée des exécutables. Si, par exemple, la version 4 est installée sur un périphérique, mais que l'utilisateur n'a jamais installé la version 3, l'application est lancée. Vérifiez la version actuelle du modèle, qui est 2. Comparez-le avec la version de l'exécutable qui est 4. Et puis appliquez le script 2 à 3, puis le script 3 à 4.
Le numéro de version lui-même peut être stocké dans la base de données et doit être incrémenté après l'application des deltas, soit à partir des deltas eux-mêmes ou automatiquement dans le code de traitement.
Les deltas peuvent être stockés sous forme de chaînes constantes dans vos fichiers de code ou simplement sous forme de fichiers de ressources dans votre projet.
Edit: (voici mon code de migration)
+ (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"];
}
Il semble que ce soit une question plus sur SQLite que Core Data. Oui? – westsider
c'était une question générale, puisque à l'époque je voulais savoir ce qui se passait lors d'une mise à niveau "app store". Mon application actuelle utilise SQLite par –