2012-04-13 2 views
7

Ich arbeite an einem iPhone-Projekt in Xcode 4.3 mit SQlite3, die Verbindung zwischen SQlite und Xcode ist fertig, jetzt möchte ich meine Daten in Tabellenansichten anzeigen (drei Ansichten) und seine nur lesen! so habe ich die Haupttabelle Ansicht, wählen Sie roh -> zur zweiten Ansicht und laden Sie andere Daten aus der DB wählen Sie roh -> nehmen Sie die Detailansicht, um langen Text und Bild anzuzeigen!So zeigen Sie Daten aus SQlite in Tabellenansichten an iPhone App an

Jede Hilfe wird geschätzt.

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

ein perfekter Fall Core Data einzurichten und eine NSFetchedResultsController verwendet Dies wäre (dies ist der genaue Zweck es entworfen wurde). Es scheint jedoch, dass Sie bereits etwas mit den nativen Bibliotheken getan haben. Bitte seien Sie genauer und zeigen Sie Code für das, was Sie getan haben. – borrrden

+0

Hier ist mein Code oben, nichts, was Sie von meinem Code bekommen können, da ich noch Anfänger bin:/ – baha

+0

Alles, was Sie brauchen, ist hier ... // Perfektes Tutorial für Sie. [SQLite mit Tabellenansicht] (http://hi.baidu.com/bailu1234/blog/item/f1a2e3170f6c455ef2de3205.html) – Nit

Antwort

0

Als erstes empfehle ich die Verwendung FMDB, die eine Objective-C-Wrapper um sqlite3 ist. Zweitens würde ich ein benutzerdefiniertes Datenzugriffsobjekt mit einer gemeinsamen Instanz erstellen, etwa so:

@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 

Dieses DAO muss 3 Zugriffsmethoden hat: einen für jedes Datenobjekt in der Datenbank. Weil Sie nicht spezifisch waren, habe ich diese Objekte ohne bestimmte Eigenschaften gemacht.

- (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; 
    } 
} 

Da es schreibgeschützt ist, sind dies alle erforderlichen Methoden. In Ihrem ersten UITableView, implementieren nur Methode:

- (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 
} 

dass alle übrig bleibt, ist nur irgendwie Ihre Datenobjekte in Ansichten zu zeigen. Ich schlage vor, so viele Daten wie möglich im Data Access Object abzulegen, damit die View Controller die Eigenschaften der Datenobjekte lesen können, ohne sich um das Backend kümmern zu müssen.

Das ist alles! Ich hoffe, das half

2

ich ein leichtes Wrapper über SQLite vorschlagen - https://github.com/JohnGoodstadt/EasySQLite

Dies sehen können:

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

UND

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

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

dies durch die Verwendung eines iVar a darstellt einrichten SQL-Tabelle:

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

Und eine DB-Verbindung iVar in der SQL-Dateinamen übergeben:

self.db = [DBController sharedDatabaseController:@"DataTable.sqlite"]; 
Verwandte Themen