7

SQlite3 を使用して Xcode 4.3 で iPhone プロジェクトに取り組んでいます。SQlite と Xcode の間の接続が完了しました。今、データをテーブル ビュー (3 つのビュー) とその読み取り専用に表示したいと考えています。だから私はメインテーブルビューを持っており、生を選択します-> 2番目のビューに移動し、DBから他のデータをロードします生を選択します->詳細ビューに移動して長いテキストと画像を表示します!

どんな助けでも感謝します。

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");

    }
}

引用符

4

2 に答える 2

2

SQLite の軽いラッパーをお勧めします - https://github.com/JohnGoodstadt/EasySQLiteを参照してください

これにより、次のことが可能になります。

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

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

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

SQL テーブルを表す iVar を使用して、これを設定します。

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

そして、SQL ファイル名を渡す DB 接続 iVar:

self.db = [DBController sharedDatabaseController:@"DataTable.sqlite"];
于 2012-09-14T16:31:01.017 に答える
0

まず、 sqlite3の Objective-C ラッパーであるFMDBを使用することをお勧めします。次に、次のように、共有インスタンスを使用してカスタム データ アクセス オブジェクトを作成します。

@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 には、データベース内のデータ オブジェクトごとに 1 つずつ、合計 3 つのアクセス メソッドが必要です。あなたは具体的ではなかったので、私はこれらのオブジェクトを特定のプロパティなしで作成しました。

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

読み取り専用なので、これらはすべて必要なメソッドです。最初の UITableView では、メソッドを実装するだけです:

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

あとは、何らかの方法でデータ オブジェクトをビューに表示するだけです。ビュー コントローラーがバックエンドを気にせずにデータ オブジェクトのプロパティを読み取れるように、データ アクセス オブジェクトで可能な限り多くのデータ取得を行うことをお勧めします。

それだけです!これが役に立ったことを願っています

于 2012-09-13T13:49:40.853 に答える