0

データベースに接続しようとしていますが、パスを NSBundle にすると成功しますが、アプリのドキュメント ディレクトリにパスを作成しようとすると成功しません。これが私のコードです:

-(IBAction)setInput:(id)sender
{
    NSString *strStoreNumber;
    NSString *strRegNumber;

    strStoreNumber = StoreNumber.text;
    strRegNumber = RegNumber.text;

    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString* documentsDirectory = [paths lastObject];
    NSString* databasePath = [documentsDirectory stringByAppendingPathComponent:@"tblStore.sqlite"];
//    NSString* databasePath = [[NSBundle mainBundle] pathForResource:@"tblStore" ofType:@"sqlite"];

    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) 
    {
        NSLog(@"Opened sqlite database at %@", databasePath);
        sqlite3_exec(database, "CREATE TABLE IF NOT EXISTS tblStore (ID INTEGER PRIMARY KEY AUTOINCREMENT, Message TEXT)", NULL, NULL, NULL);
        //...stuff
    } 
    else 
    {
        NSLog(@"Failed to open database at %@ with error %s", databasePath, sqlite3_errmsg(database));
        sqlite3_close (database);
    }
//    
    NSString *querystring;

    // create your statement
    querystring = [NSString stringWithFormat:@"SELECT strStore, strReg FROM tblStore WHERE strStore = %@ AND strReg = %@;", strStoreNumber, strRegNumber];  

    const char *sql = [querystring UTF8String];

    NSString *szStore = nil;
    NSString *szReg = nil;

    sqlite3_stmt *statement = nil;
    if (sqlite3_prepare_v2(database, sql, -1, &statement, NULL)!=SQLITE_OK) //queryString = Statement
    {
        NSLog(@"sql problem occured with: %s", sql);
        NSLog(@"%s", sqlite3_errmsg(database));
    }
    else
    {
        // you could handle multiple rows here
        while (sqlite3_step(statement) == SQLITE_ROW) 
        {            
            szStore = [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 0)];
            szReg = [NSString stringWithUTF8String:(char*)sqlite3_column_text(statement, 1)];
        }        

    }

    sqlite3_finalize(statement);

    lblStoreNumber.text = szStore;
    lblRegNumber.text = szReg; 
//   
}

次の行をコメントアウトしました。

NSString* databasePath = [[NSBundle mainBundle] pathForResource:@"tblStore" ofType:@"sqlite"];

この行がコメント化されておらず、その上の行がコメント化されている場合:

NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString* documentsDirectory = [paths lastObject];

NSString* databasePath = [documentsDirectory stringByAppendingPathComponent:@"tblStore.sqlite"];

その後、正常に動作します。ただし、これらの 3 行がコメント化されていない場合 (setInput メソッドに示されているように)、次のエラーが発生します。

2012-05-07 13:44:29.511 CCoDBTry[1981:f803] Opened sqlite database at    /Users/Matt****/Library/Application Support/iPhone Simulator/5.1/Applications/5DB7A218-A0F6-  485F-B366-91FD2F9BC062/Documents/tblStore.sqlite
2012-05-07 13:44:29.545 CCoDBTry[1981:f803] sql problem occured with: SELECT strStore, strReg FROM tblStore WHERE strStore = 8053 AND strReg = 4;
2012-05-07 13:44:29.546 CCoDBTry[1981:f803] no such column: strStore

NSBundle ロジックを使用すると、この同じデータベース テーブルにアクセスして問題なく動作することに注意してください。NSBundle と documentsDirectory の違いを完全には理解していないことは認めますが、テーブルをアプリのドキュメントに存在させたいと思います。これについて何か助けていただければ幸いです。

ありがとう!

4

3 に答える 3

2

NSBundleアプリケーション自体のリソース、つまりYourApp.app内のすべてにアクセスするために使用されます。これdocumentsDirectoryはアプリの外部の場所です。これは、アプリのサンドボックスの一部である「ホームディレクトリ」にあり、Macのユーザーのホームディレクトリに類似しています。

これらは異なる場所であるため、ある場所を使用して別の場所の同じサブパスにあるファイルを見つけることはできません。

于 2012-05-07T18:15:51.827 に答える
1

@ricksterが言っているのはこれです:

  1. Xcodeでsqliteデータベースをプロジェクトに追加すると、データベースのファイルがアプリのバンドルに追加されます。
  2. データベースをコードで作成する場合、ファイルは(ほとんどの場合)ドキュメントディレクトリに作成されます(ただし、バンドルには作成されません)。
  3. 2つの場所は完全に分離しています。バンドルはアプリのコンパイル時に作成され、後で変更することはできません。ドキュメントディレクトリは「サンドボックス化」されており、アクセスできます。ここでファイルの読み取り/書き込み/削除を行うことができます。
于 2012-05-07T19:07:57.173 に答える
1

NSBUndle から NSDocumentDirectory にコピー

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                                     NSUserDomainMask,
                                                     YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"culinary-Info.sqlite"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:path])
{
    NSString *bundle = [[NSBundle mainBundle] pathForResource:@"culinary-Info" ofType:@"sqlite"];
    [fileManager copyItemAtPath:bundle toPath:path error:nil];
}
于 2015-09-10T07:41:50.013 に答える