De PHP / MySQL / JSON a iOS / Objective-C / SQLite

Estoy intentando crear una aplicación de iOS que al cargar, inicialmente se conectará a través de HTTP a un service web PHP que emitirá datos como JSON desde una database MySQL. Entonces me gustaría importar estos datos a una database SQLite local dentro de la aplicación iOS. Ya descargué el JSON-Framework para Objective-C.

Mi pregunta es doble.

1) ¿Cuál es la mejor manera de mostrar el JSON desde PHP para que pueda enviar varias tablas de bases de datos en el mismo file JSON? Tengo 4 tablas de datos que trato de enviar (usuario, edificio, habitación, dispositivo). Así es como actualmente estoy enviando datos JSON:

// Users $query = "SELECT * from user"; $result = mysql_query($query,$conn) or die('Errant query: '.$query); $users = array(); if(mysql_num_rows($result)) { while($user = mysql_fetch_assoc($result)) { $users[] = array('user'=>$user); } } // Buildings $query = "SELECT * from building"; $result = mysql_query($query,$conn) or die('Errant query: '.$query); $buildings = array(); if(mysql_num_rows($result)) { while($building = mysql_fetch_assoc($result)) { $buildings[] = array('building'=>$building); } } // Rooms $query = "SELECT * from room"; $result = mysql_query($query,$conn) or die('Errant query: '.$query); $rooms = array(); if(mysql_num_rows($result)) { while($room = mysql_fetch_assoc($result)) { $rooms[] = array('room'=>$room); } } // Devices $query = "SELECT * from device"; $result = mysql_query($query,$conn) or die('Errant query: '.$query); $devices = array(); if(mysql_num_rows($result)) { while($device = mysql_fetch_assoc($result)) { $devices[] = array('device'=>$device); } } header('Content-type: application/json'); echo json_encode(array('users'=>$users)); echo json_encode(array('buildings'=>$buildings)); echo json_encode(array('rooms'=>$rooms)); echo json_encode(array('devices'=>$devices)); 

Me temo que este método no es la forma correcta de enviar varios objects.

2) En la aplicación iOS, ¿cómo puedo tomar automáticamente estos datos JSON e insertlos en las tablas de bases de datos locales correspondientes en SQLite?

Gracias por cualquier ayuda.

Sí, la recomendación de Luke es buena, pero estarás bien con la forma en que estás exportando tus tablas. Puede que tenga que cavar "más profundo" en la estructura para get lo que desea, es decir, su resultado con un "dictionary de dictionarys de matrices" que luego contendrá los datos para cada tabla.

En cuanto a downloadlos primero:

1) NSURLConnection y sus methods delegates: puede enviar una request asíncrona a su server web para get este file y recibir una notificación cuando se hayan descargado los datos para que la interfaz del usuario nunca se bloquee en su aplicación.

Aquí está la documentation con algunos buenos ejemplos de Apple: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html

Al final de la descarga, tendrá un object NSData que se puede volver a convertir a una cadena utilizando NSString *jsonContents = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding .

A continuación, puede usar una biblioteca de analizador JSON, recomiendo SBJSON https://github.com/stig/json-framework , que analizará los datos y los devolverá como un dictionary o arreglo dependiendo de su estructura.

Desde allí puede acceder a sus tablas y valorar con valueForKey en dictionarys o objectAtIndex: en matrices y luego objectAtIndex: a su almacenamiento local elegido, por lo que recomiendo Conetworkingata (o puede usar sqlite si también lo está).

Espero eso ayude. Rog

En 1. En lugar de JSOn puede usar lists de properties binarias que se implementan de forma nativa en el iPhone y hay una biblioteca para convertir PHP en binary Plist https://github.com/rodneyrehm/CFPropertyList

Existen muchas ventajas al usar lists de properties binarias, probablemente sean 1/5 del tamaño de JSON, no necesitas una biblioteca externa para analizarlas, por lo tanto, todo el código es mucho más simple, etc.

En 2. No hay una forma fácil de tomar la estructura JSON / Plist e insertla en una database SQL, ya que JSON / Plist permite mucha más flexibilidad que las tablas SQL. Por lo tanto, primero debería crear las tablas correctas en su database SQLite y luego usar INSERT normal para insert los datos uno por uno en la database exactamente como lo haría con PHP.

No puedo hablar con 2), pero para 1), recomiendo combinar tu JSON en una sola matriz. Una de las cosas buenas de JSON (y matrices) es la capacidad de anidar elementos tan profundamente como desee.

 echo json_encode(array( 'users'=>$users, 'buildings'=>$buildings, 'rooms'=>$rooms, 'devices'=>$devices, )); 

¿Qué hay de preparar la database SQLite en el server web y downloadla a la aplicación iOS? De esta manera, usted hace el trabajo pesado en el lado PHP. Si los datos son relativamente estáticos, incluso puede configurar una tarea progtwigda para generar la database SQLite en un intervalo regular.

Hemos hecho esto por una de nuestras aplicaciones y funcionó muy bien.

Una cosa a tener en count entonces es que debe habilitar la compression gzip en el server web para minimizar la transferencia de datos. Recuerde que tiene que hacer algunas cosas adicionales para usar la compression gzip con NSURLConnection:

http://www.bigevilempire.com/codelog/entry/nsurlconnection-with-gzip/

Puede usar el server REST y RESTKit.

Si desea una solución más completa que la ofrecida por una biblioteca de análisis independiente, le recomendamos echar un vistazo a RestKit: http://restkit.org/

El marco envuelve las operaciones de obtención, análisis y asignación de cargas útiles JSON en objects. Puede manejar estructuras profundamente anidadas y puede correlacionar directamente con Datos básicos para la persistencia.

En un nivel alto, esto es lo que sentirían sus operaciones de búsqueda y publicación en RestKit:

 - (void)loadObjects { [[RKObjectManager shanetworkingManager] loadObjectsAtResourcePath:[@"/path/to/stuff.json" delegate:self]; } - (void)objectLoader:(RKObjectLoader*)loader didLoadObjects:(NSArray*)objects { NSLog(@"These are my JSON decoded, mapped objects: %@", objects); // Mutate and PUT the changes back to the server MyObject* anObject = [objects objectAtIndex:0]; anObject.name = @"This is the new name!"; [[RKObjectManager shanetworkingManager] putObject:anObject delegate:self]; } 

El marco se ocupa del análisis / encoding JSON en un hilo de background y le permite declarar cómo los attributes en el map JSON a las properties de su object. Varias personas en la comunidad están trabajando con PHP backends + RestKit con gran éxito.