2010-05-04 7 views
9

J'ai actuellement une application iPhone dans le magasin d'applications iTunes qui utilise une base de données SQLite comme magasin de données. L'utilisateur peut synchroniser l'application avec un service Web et les données renvoyées sont ensuite stockées dans la base de données SQLite. L'utilisateur peut également insérer de nouveaux éléments dans la base de données et synchroniser leurs modifications sur le service Web. Lorsqu'une connexion est ouverte à la base de données locale de l'application, le code vérifie que le fichier de base de données existe dans le dossier "Documents" si la base de données n'est pas créée en étant copiée du dossier "Resources" vers le dossier "Documents".Comment mettre à jour SQLite DB sur la mise à jour de l'application iPhone?

Je dois publier une mise à jour de l'application. La mise à jour contient des modifications de schéma de base de données (nouvelles tables, colonnes, etc.). D'après ce que j'ai lu, les fichiers dans le répertoire "Documents" persisteront sur une mise à jour d'application, ce qui signifie que la base de données existante sera toujours intacte après la mise à jour.

Ma question est, comment puis-je remplacer la base de données existante avec ma base de données mise à jour et est-il un moyen de le faire sans perdre les données dans la base de données existante? Existe-t-il une sorte d'événement "première exécution après mise à jour" avec lequel je peux travailler pour effectuer la mise à jour de base de données ou dois-je effectuer une vérification sur la base de données existante? remplacer/mettre à jour manuellement la base de données?

Merci!

+0

un regard sur ce lien pour une enveloppe sqlite qui permet des opérations plus faciles SQLite - https://github.com/ccgus/fmdb/ –

Répondre

15

Vous devriez stocker le numéro de version actuel de l'application quelque part de façon persistante - dans la base de données ou, mieux encore, dans la base de données par défaut. Au démarrage, votre application compare son propre numéro de version avec le numéro de version persistante. Si elles diffèrent, il s'agit de la première exécution après une mise à jour. Si le numéro de version persistant n'est pas là, alors évidemment c'est aussi le premier lancement après une mise à jour. En ce qui concerne la mise à jour de votre base de données, si elle est en place, vous utiliserez les commandes SQL ALTER habituelles pour mettre à jour votre schéma et effectuer une migration de données de base de données en même temps.

+0

Donc, il n'y a pas construit « application mise à jour » ou « premier courir après mise à jour "événement/vérifier ou quelque chose comme ça? On dirait que je vais devoir vérifier les versions sur chaque chargement d'application? – Billy

+0

Pas que je sache, mais certainement s'il y en a, il serait facile de trouver dans les docs ... –

3

Nous vérifions les mises à jour en interrogeant le serveur pour une valeur de hachage dans l'en-tête d'un plist qui est craché via un fichier php qui interroge la base de données du serveur. Vous pouvez stocker ce hachage localement et le comparer à la dernière exécution de l'application. De cette façon, le téléphone sait si sa version est périmée. Ensuite, nous téléchargeons le nouveau plist en arrière-plan et mettons à jour la base de données sur le téléphone.

EDIT:

A la fin de notre php, nous obtenons un MD5 de la sortie XML du plist nous générons sur le serveur comme ceci:

header("MD5-Hash: ". md5($xml_output)); 
echo $xml_output; 

Ensuite, nous obtenons le hachage le plist sur l'iPhone de userDefaults comme ceci:

NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; 
curHash = [defaults stringForKey:kUpdateUserDefault]; 

Et le hachage du serveur de la NSURLRequest, comme ceci:

NSString *hash = [[[res allHeaderFields] objectForKey:kUpdateHeaderField] retain]; 

Ensuite, nous comparons les deux et télécharger le document que si les hachages ne correspondent pas:

if (![curHash isEqualToString:hash]) { 
      [self performSelector:@selector(sendUpdateStarted) onThread:[NSThread mainThread] withObject:nil waitUntilDone:NO]; 
      ... download the file and save it as the new iPhone's plist 
    } 

Ce code est écrit par mon partenaire très compétent, Oliver Rice.

+0

Je ne comprends pas vraiment votre réponse. Le hachage de quel pliste? –

+0

S'il vous plaît voir les modifications ci-dessus dans ma réponse originale. –

+0

Il semble que cela ait aussi l'avantage de prévenir le piratage. – Jess

4

sqlite3 * base de données; sqlite3_stmt * update_statement = nil;

if(sqlite3_open([strDatabasePath UTF8String], &database) == SQLITE_OK) 
{ 
    nsstring *strMQueryupdate="write your query here"; 

    const char *sql = [strMQueryupdate UTF8String]; 

    if (sqlite3_prepare_v2(database, sql, -1, &update_statement, NULL) != SQLITE_OK) { 
     NSLog(@"update fails"); 
    } 
    else 
    { 
     sqlite3_bind_text(update_statement, 1, [[arrayname objectAtIndex:0] UTF8String], -1, SQLITE_TRANSIENT); 


     int success = sqlite3_step(update_statement); 
     sqlite3_reset(update_statement); 
     if (success == SQLITE_ERROR){} 
     else {} 
    } 
    sqlite3_finalize(update_statement); 
} 
sqlite3_close(database); 
Questions connexes