Aplicaciones para MAC con XCode y SQLite

1 Estrella2 Estrellas3 Estrellas4 Estrellas5 Estrellas, Wow! (1 votos, media: 5,00 ,total: 5)

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 <Cocoa/Cocoa.h>
#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"] &amp;&amp;
              [[rs columnNameForIndex:1] isEqualToString:@"usuario"])
			) {
            NSLog(@"WHOA THERE BUDDY, columnNameForIndex ISN'T WORKING!");
            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];
		}
    }
    // close the result set.
    // it'll also close when it's dealloc'd, but we're closing the database before
    // the autorelease pool closes, so sqlite will complain about it.
    [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 <Cocoa/Cocoa.h>
#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 <Cocoa/Cocoa.h>

@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 <Cocoa/Cocoa.h>
#import "bd.h"

#import "controlador.h"

int main(int argc, char *argv[])
{

    return NSApplicationMain(argc,  (const char **) argv);
}

Artículos relacionados:

  1. Dalboz dice:

    Muy ilustrativo tu post! gracias!

footer
jbelon ©