2012-04-13 7 views
7

Pracuję nad projektem iPhone'a w Xcode 4.3 z SQlite3, połączenie między SQlite i Xcode jest zakończone, teraz chcę wyświetlić moje dane w widoku tabeli (trzy widoki) i tylko do odczytu! , więc mam główny widok tabeli, wybierz raw -> take to 2nd view i załaduj inne dane z DB select raw -> take to the details view, aby wyświetlić długi tekst i obraz!Jak wyświetlać dane z SQlite w widoku tabeli do aplikacji iPhone'a

Każda pomoc doceniona.

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

Byłby to idealny przypadek skonfigurować danych Core i użyć NSFetchedResultsController (to jest dokładny cel został zaprojektowany dla). Wydaje się jednak, że już zrobiłeś ... ** coś ** ... z natywnymi bibliotekami. Podaj więcej szczegółów i pokaż kod tego, co zrobiłeś. – borrrden

+0

Oto mój kod powyżej, nic nie można uzyskać z mojego kodu, ponieważ wciąż jestem początkujący:/ – baha

+0

Wszystko, czego potrzebujesz, jest tutaj ... // Idealny samouczek dla ciebie. [Sqlite with tableview] (http://hi.baidu.com/bailu1234/blog/item/f1a2e3170f6c455ef2de3205.html) – Nit

Odpowiedz

0

Przede wszystkim sugeruję użycie FMDB, która jest otoczką Objective-C wokół sqlite3. Po drugie, chciałbym utworzyć niestandardową Data Access Object ze wspólną przykład tak:

@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 

DAO to musi mieć 3 metody dostępu: jeden dla każdego obiektu w bazie danych. Ponieważ nie byłeś konkretny, zrobiłem te obiekty bez żadnych konkretnych właściwości.

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

Ponieważ są to tylko do odczytu, są to wszystkie wymagane metody. W swoim pierwszym UITableView, po prostu wdrożyć metodę:

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

Pozostaje jest tylko, aby pokazać swoje obiekty danych w widokach jakoś. Sugeruję, aby w obiekcie Data Access Object uzyskać jak najwięcej danych, aby kontrolery widoku mogły odczytać właściwości obiektów danych bez martwienia się o backend.

To wszystko, o to chodzi! Mam nadzieję, że to pomogło

2

proponuję lekką owijkę nad SQLite - patrz https://github.com/JohnGoodstadt/EasySQLite

Pozwoli to:

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

I

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

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

to skonfigurować przy użyciu Ivar reprezentujących Tabela SQL:

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

i połączenie DB Ivar przechodząc w nazwie pliku SQL:

self.db = [DBController sharedDatabaseController:@"DataTable.sqlite"]; 
Powiązane problemy