4

sqliteデータベースからデータを読み取り、iOSアプリのテーブルビューに表示しようとしています。しかし、何らかの理由でsqliteデータベースを開くことができず、アプリがクラッシュして「データベースを開けませんでした」というメッセージが表示されます。

Firefox sqlite managerを使用してデータベースを作成し、ファイルをXcodeプロジェクトにコピーしました。

これが私のコードです-

-(NSString *)dataFilePath{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
    NSString *documentsDir = [paths objectAtIndex:0];
    return [documentsDir stringByAppendingPathComponent:kFilename];
}

viewDidLoad内でsqlite3_open_v2コマンドを使用してデータベースを開こうとしています

sqlite3 *database;

    if (sqlite3_open_v2([[self dataFilePath] UTF8String], &database, SQLITE_OPEN_READWRITE, NULL) != SQLITE_OK) {
        sqlite3_close(database); // not sure you need to close if the open failed
        NSAssert(0, @"Failed to open database");
    }
4

2 に答える 2

13

これが私のデータベースを開く方法です。私は長い間SQLiteを使用しておらず、自分のアプリケーションで使用するこのコードを提供する以外に、多くの支援を提供することはできません。これは、アプリで使用しているクラスからのものです。

static sqlite3 *database;
static sqlite3_stmt *enableForeignKey;

@implementation DBAdapter

+ (sqlite3 *)sharedInstance {

    if (database == NULL) {
        sqlite3 *newDBconnection;

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *path = [documentsDirectory stringByAppendingPathComponent:@"klb_db.sqlite"];

        if (sqlite3_open([path UTF8String], &newDBconnection) == SQLITE_OK) {   
            //NSLog(@"Database Successfully Opened :)");
            database = newDBconnection;

            if (sqlite3_prepare_v2(database, "PRAGMA foreign_keys = ON", -1, &enableForeignKey, NULL) != SQLITE_OK) {
                NSLog(@"ERROR IN PRAGMA!");
            }

            sqlite3_finalize(enableForeignKey);

        } else {
            NSLog(@"Error in opening database :(");
            database = NULL;
        }
    }

    return database;
}
于 2012-06-28T20:29:30.487 に答える
3

iosのコメントでの議論中にあなたの質問が答えられたと仮定して私は正しいですか-sqliteprepareステートメント?つまり、データベースがバンドルに含まれていること(ターゲットの「ビルドフェーズ」のXcodeで「バンドルリソースのコピー」設定を確認することにより)、およびデータベースの存在をアプリに確認させたいことを確認します。ドキュメントフォルダにあり、存在しない場合は、バンドル([[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:kFilename])からドキュメントフォルダにコピーします。

これは元の質問の範囲を超えている可能性がありますが、アプリの最終的なデプロイ、さらに重要なことに、アプリのその後のアップグレード/リリースを検討するときに、内部データベースのバージョン番号を使用してデータベースにテーブルを追加することをお勧めしますこれを使用して、ユーザーがドキュメントフォルダーにあるデータベースのバージョンを判別し、アプリの最新バージョンをサポートするために必要になる可能性のあるデータベースに変更を加えることができます。ちょっとした考え。

とにかく、まだ未解決の質問がある場合は、お知らせください。それ以外の場合は、質問が解決したと思います。

于 2012-06-29T00:35:06.217 に答える