He estado realizando en los últimos meses algunas tareas para clientes, tanto extranjeros (de Grecia) como locales y aquí van algunos consejos a raíz de las experiencias que he tenido tras la investigación del IDE XCode y del Snow Leopard.
Ahora os muestro un vídeo con un ejemplo sencillo de lo que se puede hacer con Objetive C de XCode de Apple y SQlite, creación de una base de datos, una tabla y dos tuplas para luego mostrarla en un objeto de Cocoa:
Lo primero, para diseñar interfaces y escribir código hay que descargarse las herramientas, esto es, la última versión de XCode y las Developers Tools, así podremos compilar el código que escribamos asociado a las interfaces.
Para poder tener un almacén de datos exportable y que se pueda utilizar en cualquier plataforma (iPhone,iPod, PC, MAC,etc) usaremos SQLite, y para comunicar este motor con XCode usaremos el framework FMDB (del cual hay una versión específica para iPhone/iPod) ,esto es tan fácil como descargarse el framework y copiar los ficheros, después se crea una clase base de datos como esta:
#import #import "FMDatabase.h" #import "FMDatabaseAdditions.h" #define FMDBQuickCheck(SomeBool) { if (!(SomeBool)) { NSLog(@"Failure on line %d", __LINE__); return 123; } } @interface bd : NSObject { FMDatabase *fmdb; } - (void) crearBD; @end
La implementación:
#import "bd.h" @implementation bd - (void) crearBD { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; fmdb = [FMDatabase databaseWithPath: @"/Users/juaxix/Documents/miBD.sqlite"]; if (![fmdb open]) { NSLog(@"No se pudo abrir la base de datos."); [pool release]; return NULL; } return self; } -(NSMutableArray*) seleccionSQL:(NSString*)sql{ FMResultSet *rs = [fmdb executeQuery:sql, @"hi'"]; NSMutableArray *datos = [[NSMutableArray alloc] init] ; while ([rs next]) { // just print out what we've got in a number of formats. /* NSLog(@"%d %@ %@ %@ %@ %f %f", [rs intForColumn:@"c"], [rs stringForColumn:@"b"], [rs stringForColumn:@"a"], [rs stringForColumn:@"rowid"], [rs dateForColumn:@"d"], [rs doubleForColumn:@"d"], [rs doubleForColumn:@"e"]); */ if (!([[rs columnNameForIndex:0] isEqualToString:@"idu"] && [[rs columnNameForIndex:1] isEqualToString:@"usuario"]) ) { return 7; } else { NSString *cadena = [NSString stringWithFormat: @"idu: %d usuario:%@ ",[rs intForColumn:@"idu"], [rs stringForColumn:@"usuario"]]; NSLog( cadena ); NSMutableArray *aux = [[NSMutableArray alloc] init]; [aux addObject:[NSString stringWithFormat:@"%d", [rs intForColumn:@"idu"]]]; [aux addObject:[NSString stringWithFormat:@"%@", [rs stringForColumn:@"usuario"]]]; [aux addObject:[NSString stringWithFormat:@"%@", [rs stringForColumn:@"email"]]]; [datos addObject:aux]; } } [rs close]; return datos; } @end
Ahora que tenemos la base de datos debemos crear un controlador para asociar las acciones de la Interfaz al código fuente, algo sencillo como esto:
#import #import "bd.h" @interface controlador : NSObject { IBOutlet NSTableView *tablaDatos; bd *mi_bd; } - (IBAction)cargarDatos:(id)sender; @end
esta es la implementación
#import "controlador.h" #import "bd.h" #import "personas.h" @implementation controlador - (IBAction)cargarDatos:(id)sender { if (!mi_bd){ mi_bd = [[bd alloc] init] ; [mi_bd crearBD]; } NSMutableArray *datos = [mi_bd seleccionSQL: @"select * from usuarios"]; if (datos){ //Ahora vamos a meter los datos en el objeto personas *p = [[personas alloc] init]; [p meterDatos:datos]; [tablaDatos setDataSource:p]; } } @end
Como hace falta una clase que le de los datos a la vista de tabla (el datagrid) he creado una llamada personas:
#import @interface personas : NSObject { NSMutableArray *datos; } -(void) meterDatos:(NSMutableArray*)kdatos; - (int)numberOfRowsInTableView:(NSTableView *)tableView; - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *) tableColumn row:(int)row; @end
esta clase implementa las acciones que necesita este tipo de objeto para representar la información y poder acceder a los datos…
#import "personas.h" @implementation personas -(void) meterDatos:(NSMutableArray*) kdatos { datos = kdatos; } - (int)numberOfRowsInTableView:(NSTableView *)tableView{ return [datos count]; } - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row { id value =nil; //creamos un objeto NSString *identifier =[tableColumn identifier]; NSMutableArray *aux =[datos objectAtIndex:row]; /*creamos un objeto de la clase que queremos listar y le asignamos el valor de la fila en la que estamos*/ if ([identifier isEqual:@"id"]) value=[aux objectAtIndex:0]; else if ([identifier isEqual:@"nombre"]) value=[aux objectAtIndex:1]; else if([identifier isEqual:@"email"]) value=[aux objectAtIndex:2]; else NSLog("No encuentro el valor"); NSLog([aux objectAtIndex:0]); return value; } @end
y básicamente ya lo tenemos todo, el main es una línea:
#import #import "bd.h" #import "controlador.h" int main(int argc, char *argv[]) { return NSApplicationMain(argc, (const char **) argv); }
Muy ilustrativo tu post! gracias!
Me alegro de que te haya ilustrado, a mí me resultó complejo al principio encontrar un poco de claridad para empezar :D
Realmente fabuloso. Estoy empezando, no llevo más de 2 horas con la aplicación, pero creo que continuaré. Feliz Navidad!
Ese es el espíritu! sigue así :)
Juan soy de una universidad de Sinaloa, México y estoy iniciando con esto de la programada para iphone, a estas alturas es el mejor famework que has usado FMDB.
Saludos y espero sigas así, muchas gracias.
Hola Roberto,FMDB está anticuado, desde que incrustaron SQLite en XCode es mejor utilizar el modelo de datos de Apple porque es más sencillo de utilizar aunque tienes que investigarlo un poco eso sí…de nada