2010-05-04 12 views
9

Actualmente tengo una aplicación de iPhone en la tienda de aplicaciones de iTunes que usa una base de datos SQLite como almacén de datos. El usuario puede sincronizar la aplicación con un servicio web y los datos que se devuelven se almacenan en la base de datos SQLite. El usuario también puede insertar nuevos elementos en la base de datos y sincronizar sus cambios con el servicio web.¿Cómo actualizar la actualización de la aplicación SQLite DB en el iPhone?

Cuando se abre una conexión a la base de datos local de la aplicación, el código comprueba que el archivo de base de datos existe en la carpeta "Documentos", si no se crea la base de datos copiando de la carpeta "Recursos" a la carpeta "Documentos".

Tengo que lanzar una actualización de la aplicación. La actualización contiene cambios en el esquema de la base de datos (nuevas tablas, columnas, etc.). Según lo que he leído, los archivos en el directorio "Documentos" persistirán en la actualización de la aplicación, lo que significa que la base de datos existente seguirá intacta después de la actualización.

Mi pregunta es, ¿cómo puedo reemplazar la base de datos existente con mi base de datos actualizada y hay una manera de hacerlo sin perder los datos en la base de datos existente? ¿Existe algún tipo de evento de "primera ejecución después de la actualización" con el que pueda trabajar para realizar la actualización de la base de datos, o tengo que hacer algún tipo de comprobación en la base de datos existente (buscar una nueva columna o tabla) y si falla mi verificación? reemplazar/actualizar manualmente la base de datos?

Gracias!

+0

echar un vistazo a este enlace para un envoltorio de SQLite SQLite que permite operaciones más sencillas - https://github.com/ccgus/fmdb/ –

Respuesta

15

Debe almacenar el número de versión actual de la aplicación en algún lugar persistente - en la base de datos o mejor aún en la base de datos por defecto. Al inicio, su aplicación comparará su propio número de versión con el número de versión subsistente. Si difieren, entonces esta es la primera ejecución después de una actualización. Si el número de versión persistente no está allí, obviamente también esta es la primera ejecución después de una actualización.

En cuanto a la actualización de su base de datos, si está en su lugar utilizaría los comandos SQL ALTER habituales para actualizar su esquema, y ​​hacer cualquier migración de datos de base de datos al mismo tiempo.

+0

Así que no hay una construida en la "aplicación actualizada" o "primera ejecutar después de la actualización "evento/verificación o algo por el estilo? ¿Parece que voy a tener que verificar las versiones en cada carga de la aplicación? – Billy

+0

No es que yo sepa, pero ciertamente si lo hay sería fácil de encontrar en los documentos ... –

3

Comprobamos las actualizaciones consultando al servidor un valor hash en el encabezado de un plist que se escupe a través de un archivo php que consulta la base de datos del servidor. Puede almacenar ese hash localmente y compararlo con la última vez que se ejecutó la aplicación. De esa forma, el teléfono sabe si su versión está desactualizada. Luego descargamos el nuevo plist en segundo plano y actualizamos la base de datos en el teléfono.

EDIT:

Al final de nuestra php, obtenemos un MD5 de la salida XML de la plist estamos generando en el servidor de la siguiente manera:

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

A continuación, obtener el hash el plist en el iPhone de userDefaults así:

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

Y hash del servidor de la NSURLRequest, así:

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

A continuación, comparar los dos y empezar la descarga sólo si los valores hash no coinciden:

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 
    } 

Este código está escrito por mi compañero muy capaz, Oliver Rice.

+0

Realmente no entiendo tu respuesta. ¿El hash de qué plist? –

+0

Consulte las ediciones anteriores en mi respuesta original. –

+0

Parece que esto también tiene el beneficio adicional de prevenir la piratería. – Jess

4

sqlite3 * base de datos; 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); 
Cuestiones relacionadas