2012-05-07 48 views
0

我想連接到一個數據庫,我發現它是成功的,當我讓路徑去NSBundle,但不是當我嘗試讓路徑在我的應用程序的文檔目錄。這裏是我的代碼:爲什麼NSBundle mainBundle工作,但不是documentsDirectory?

-(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"]; 

然後它工作正常。但是,如果這些三線沒有被註釋掉(如圖所示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之間的差異,但我想我會想我的表在我的應用程序的文件是否存在。我將不勝感激任何幫助。

謝謝!

回答

2

NSBundle用於訪問您的應用程序本身內的資源:也就是說,所有內容ide YourApp.app。 documentsDirectory位於應用程序外部,位於您的應用程序沙箱的「主目錄」中,該目錄與Mac上的用戶主目錄類似。

這些是不同的位置,所以使用其中一個在另一個子路徑中查找文件不起作用。

+0

那麼,爲什麼不定位strStore列時,我在DocumentsDirectory工作創建的路徑?該列在使用NSBundle邏輯時找到。你介意詳細說明我的代碼可能有什麼問題嗎?目標是爲我的sqlite表創建一個路徑到iPhone上的文檔文件夾。我被挖掘出來了,所以這裏的任何幫助將不勝感激。謝謝! – Skizz

1

什麼@rickster是說是這樣的:

  1. 如果SQLite數據庫添加到Xcode中的項目,在數據庫中的文件被添加到您的應用程序的包。
  2. 如果您使用代碼創建數據庫,該文件將(很可能)在您的文檔目錄中創建(但肯定不在您的軟件包中)。
  3. 這兩個位置是完全是分開。您的軟件包是在編譯應用程序時創建的,並且以後不能更改。您的文檔目錄是「沙盒」,它允許您訪問它;你可以在這裏讀/寫/刪除文件。從一個NSBundle
+0

有趣。所以爲了讓我有一個位於我的文檔目錄中的數據庫表的副本,我必須創建表(通過代碼),對嗎?感謝您的迴應! – Skizz

+0

我不知道如何將文件添加到文檔目錄,除非通過代碼添加它們。不過,如果我錯了,我很想糾正這個問題。 – mbm29414

+0

您可以在應用程序包中發佈文件,然後使用NSFileManager將其複製到文檔目錄中。 – rickster

1

複製到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]; 
} 
相關問題