2010-05-04 15 views
9

Ich habe derzeit eine iPhone-App im iTunes App Store, die eine SQLite-Datenbank als Datenspeicher verwendet. Der Benutzer kann die App mit einem Webdienst synchronisieren und Daten, die zurückgegeben werden, werden dann in der SQLite-Datenbank gespeichert. Der Benutzer kann auch neue Elemente in die Datenbank einfügen und deren Änderungen mit dem Web-Service synchronisieren.Wie aktualisiert man die SQLite DB auf dem iPhone App Update?

Wenn eine Verbindung zur lokalen Datenbank der App geöffnet wird, prüft der Code, ob die Datenbankdatei im Ordner "Dokumente" vorhanden ist, wenn die Datenbank nicht erstellt wird, indem sie aus dem Ordner "Resources" kopiert wird der Ordner "Dokumente".

Ich muss ein Update für die App veröffentlichen. Das Update enthält Datenbankschemaänderungen (neue Tabellen, Spalten usw.). Nach dem, was ich gelesen habe, werden Dateien im Verzeichnis "Dokumente" bei einem App-Update beibehalten, was bedeutet, dass die vorhandene Datenbank nach dem Update noch intakt ist.

Meine Frage ist, wie ersetze ich die vorhandene Datenbank mit meiner aktualisierten Datenbank und gibt es eine Möglichkeit, dies zu tun, ohne die Daten in der vorhandenen Datenbank zu verlieren? Gibt es eine Art "erstes Ausführen nach Update" -Ereignis, mit dem ich arbeiten kann, um die Datenbank zu aktualisieren, oder muss ich eine Überprüfung der vorhandenen Datenbank durchführen (nach einer neuen Spalte oder Tabelle suchen) und wenn meine Prüfung fehlschlägt die Datenbank manuell ersetzen/aktualisieren?

Danke!

+0

haben einen Blick auf diesem Link für einen SQLite-Wrapper, die einfachen SQLite Operationen ermöglicht - https://github.com/ccgus/fmdb/ –

Antwort

15

Sie sollten die aktuelle Versionsnummer der App dauerhaft speichern - in der Datenbank oder noch besser in der Defaults-Datenbank. Beim Start vergleicht Ihre App die eigene Versionsnummer mit der beibehaltenen Versionsnummer. Wenn sie sich unterscheiden, ist dies der erste Durchlauf nach einem Update. Wenn die persistente Versionsnummer nicht vorhanden ist, ist dies natürlich auch der erste Durchlauf nach einem Update.

Wenn Sie Ihre Datenbank aktualisieren, verwenden Sie die üblichen SQL ALTER-Befehle, um Ihr Schema zu aktualisieren und alle Datenbankdatenmigration gleichzeitig durchzuführen.

+0

So gibt keine in „app aktualisiert“ oder „zuerst gebaut ist run after update "event/check oder ähnliches? Klingt so, als müsste ich die Versionen bei jeder App laden? – Billy

+0

Nicht, dass ich weiß, aber sicherlich, wenn es wäre leicht zu finden in den Dokumenten ... –

3

Wir suchen nach Updates, indem wir den Server nach einem Hashwert in der Kopfzeile eines PLIST abfragen, der über eine PHP-Datei, die die Serverdatenbank abfragt, ausgespuckt wird. Sie können diesen Hash lokal speichern und ihn mit dem letzten Ausführen der App vergleichen. Auf diese Weise weiß das Telefon, ob seine Version veraltet ist. Dann laden wir das neue plist im Hintergrund herunter und aktualisieren die Datenbank am Telefon.

EDIT:

Am Ende unserer php, erhalten wir eine MD5 der XML-Ausgabe des plist wir auf dem Server wie folgt generieren:

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

Dann erhalten wir die Hash der plist auf dem iPhone von userDefaults wie so:

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

und der Hash-Server aus dem NSURLRequest, etwa so:

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

Dann vergleichen wir die beiden und den Download starten, nur wenn die Hashes nicht übereinstimmen:

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 
    } 

Dieser Code von meiner sehr kompetenten Partner, Oliver Rice geschrieben.

+0

Ich verstehe nicht wirklich deine Antwort. Das Hasch von was plist? –

+0

Bitte beachten Sie die obigen Änderungen in meiner ursprünglichen Antwort. –

+0

Es hat den zusätzlichen Vorteil, Piraterie zu verhindern. – Jess

4

sqlite3 * Datenbank; sqlite3_stmt * update_statement = null;

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); 
Verwandte Themen