2012-04-13 21 views
7

Estoy trabajando en un proyecto de iPhone en Xcode 4.3 con SQlite3, la conexión entre SQlite y Xcode ya está hecha, ahora quiero mostrar mis datos en una tabla de visitas (tres vistas) ¡y es solo de lectura! así que tengo la vista de tabla principal, seleccione raw -> lleve a la segunda vista y cargue otros datos desde la base de datos seleccione raw -> lleve a la vista de detalles para mostrar el texto largo y la imagen!Cómo mostrar datos de SQlite en vistas de tabla a la aplicación de iPhone

Cualquier ayuda apreciada.

AppDelegate.h

#import "AppDelegate.h" 

#import "MasterViewController.h" 

@implementation AppDelegate 

@synthesize window = _window; 
@synthesize navigationController = _navigationController; 

- (void)dealloc 
{ 
    [_window release]; 
    [_navigationController release]; 
    [super dealloc]; 
} 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; 
    // Override point for customization after application launch. 


    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDir = [paths objectAtIndex:0]; 

    NSString *dbPath = [documentsDir stringByAppendingPathComponent:@"cities.sqlite"]; 

    NSFileManager *fileManager = [NSFileManager defaultManager]; 

    BOOL success = [fileManager fileExistsAtPath:dbPath]; 

    if (success) { 

     NSLog(@"we have the database"); 

    } else { 

     NSLog(@"we have no database"); 

     NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"cities.sqlite"]; 


     BOOL moved = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:nil]; 

     if (moved) { 
      NSLog(@"database copied"); 
     } 

    } 


    MasterViewController *masterViewController = [[[MasterViewController alloc] initWithNibName:@"MasterViewController" bundle:nil] autorelease]; 
    self.navigationController = [[[UINavigationController alloc] initWithRootViewController:masterViewController] autorelease]; 
    self.window.rootViewController = self.navigationController; 
    [self.window makeKeyAndVisible]; 
    return YES; 
} 

MasterViewController.h

#import <UIKit/UIKit.h> 
#import <sqlite3.h> 


@class DetailViewController; 

@interface MasterViewController : UITableViewController { 
    NSMutableArray *cities; 
} 

@property (strong, nonatomic) DetailViewController *detailViewController; 

@end 

MasterViewController.m

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    students = [[NSMutableArray alloc] init]; 
    countries = [[NSMutableArray alloc] init]; 

    // Do any additional setup after loading the view, typically from a nib. 
    self.navigationItem.leftBarButtonItem = self.editButtonItem; 

    UIBarButtonItem *addButton = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)] autorelease]; 
    self.navigationItem.rightBarButtonItem = addButton; 


    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDir = [paths objectAtIndex:0]; 
    NSString *dbPath = [documentsDir stringByAppendingPathComponent:@"cities.sqlite"]; 


    sqlite3 *database; 

    if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) { 

     const char *sqlStatement = "select * from cities_info"; 

     sqlite3_stmt *compileStatement; 

     if (sqlite3_prepare_v2(database, sqlStatement, -1, &compileStatement, NULL) == SQLITE_OK) { 


      while (sqlite3_step(compileStatement) == SQLITE_ROW) { 

       NSLog(@"one record"); 

       NSString *cityName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compileStatement, 1)]; 

       [cities addObject:cityName]; 

      } 

      NSLog(@"cities: %@",cities); 

     } 


    } else { 


     NSLog(@"error in database"); 

    } 
} 

Blockquote

+0

Este sería un caso perfecto para establecer la base de datos y utilizar un NSFetchedResultsController (este es el propósito exacto que fue diseñado). Sin embargo, parece que ya has hecho ... ** algo ** ... con las bibliotecas nativas. Sea más específico y muestre el código de lo que ha hecho. – borrrden

+0

aquí está mi código de arriba, no hay mucho que pueda obtener de mi código porque aún soy principiante:/ – baha

+0

Todo lo que necesita está aquí ... // Tutorial perfecto para usted. [Sqlite con tabla vista] (http://hi.baidu.com/bailu1234/blog/item/f1a2e3170f6c455ef2de3205.html) – Nit

Respuesta

0

Antes que nada, sugiero usar FMDB, que es un contenedor Objective-C alrededor de sqlite3. En segundo lugar, me gustaría crear una costumbre de acceso a datos de objetos con una instancia compartida, así:

@interface MyDatabaseDAO : NSObject 
    @property (nonatomic, strong) FMDatabase *database; 
@end 


@implementation MyDatabaseDAO 
@synthesize database = _database; 

+ (MyDatabaseDAO *)instance { 
    static MyDatabaseDAO *_instance = nil; 

    @synchronized (self) { 
     if (_instance == nil) { 
      _instance = [[self alloc] init]; 
     } 
    } 

    return _instance; 
} 

- (id)init { 
    self.database = [FMDatabase databaseWithPath:myDatabasePath]; 
    [self.database open]; 
} 

- (void)dealloc { 
    [self.database close]; 
} 
@end 

Este DAO debe tener métodos de acceso 3: una para cada objeto de datos en la base de datos. Porque no eras específico, hice estos objetos sin ninguna propiedad específica.

- (NSArray *)retrieveAllFirstViewItems { 
    NSMutableArray *items = [NSMutableArray array]; 
    FMResultSet *resultSet = [FMDBDatabase.database executeQuery:@"SELECT * FROM myFirstViewItemTable"];  

    while ([resultSet next]) { 
     // extract whatever data you want from the resultset 
     NSString *name = [resultSet stringForColumn:@"name"] 
     [items addObject:name]; 
    } 
    [resultSet close]; 

    return items; 
} 

- (MySecondViewItem *)retrieveSecondViewItemFromIndexPath:(NSIndexPath *)indexPath { 

    FMResultSet *resultSet = [FMDBDatabase.database executeQuery:@"SELECT * FROM mySecondViewItemTable WHERE pid = ?", [indexPath indexAtPosition:0]]; 
    if ([resultSet next]) { 
     // extract whatever data you want from the resultset 
     NSString *name = [resultSet stringForColumn:@"name"] 
     MySecondViewItem *mySecondViewItem = [[MySecondViewItem alloc] 
       initWithName:name withPID:[indexPath indexAtPosition:0]]; 
     [resultSet close]; 
     return mySecondViewItem; 
    } else { 
     return nil; 
    } 
} 

- (MyThirdViewItem *)retrieveThirdViewItemFromIndexPath:(NSIndexPath *)indexPath { 

    FMResultSet *resultSet = [FMDBDatabase.database executeQuery:@"SELECT * FROM mySecondViewItemTable WHERE pid = ?", [indexPath indexAtPosition:1]]; 
    if ([resultSet next]) { 
     // extract whatever data you want from the resultset 
     NSString *name = [resultSet stringForColumn:@"name"] 
     MyThirdViewItem *myThirdViewItem = [[MyThirdViewItem alloc] 
       initWithName:name withPID:[indexPath indexAtPosition:1]]; 
     [resultSet close]; 
     return myThirdViewItem; 
    } else { 
     return nil; 
    } 
} 

Como son de solo lectura, estos son todos los métodos requeridos. En su primera UITableView, simplemente implementar el método:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
    MySecondViewItem *mySecondViewItem = [[MyDatabaseDAO instance] retrieveSecondViewItemFromIndexPath:indexPath]; 
    //instantiate a view from this item and use [UINavigationController pushViewController:animated:] to navigate to it 
} 

Todo lo que queda es sólo para mostrar sus objetos de datos en vistas de alguna manera. Sugiero hacer la mayor cantidad posible de recuperación de datos en el Objeto de acceso a datos para que los controladores de vista puedan leer las propiedades de los objetos de datos sin tener que preocuparse por el back-end.

¡Eso es todo! Espero que esto ayudó

2

que sugieren un envoltorio de luz sobre SQLite - ver https://github.com/JohnGoodstadt/EasySQLite

Esto permitirá:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return _personTable.rows.count; 
} 

Y

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    ... 

    NSArray* row= _personTable.rows[indexPath.row]; 
    cell.textLabel.text = row[[_personTable colIndex:@"lastname"]]; 
    ... 

configurar esto mediante el uso de una Ivar que representa una Tabla de SQL:

self.personTable = [_db ExecuteQuery:@"SELECT firstname , lastname , age , salary FROM person"]; 

y una conexión DB Ivar pasando en su nombre de archivo de SQL:

self.db = [DBController sharedDatabaseController:@"DataTable.sqlite"]; 
Cuestiones relacionadas