简体   繁体   English

为什么NSBundle mainBundle可以工作,而documentDirectory不能工作?

[英]Why does NSBundle mainBundle work, but not documentsDirectory?

I am trying to to make a connection to a database and I'm finding that it is successful when I make the path go to NSBundle, but not when I try make the path be in my app's documents directory. 我试图建立与数据库的连接,但是当我将路径转到NSBundle时,我发现它成功了,但是当我尝试将路径置于应用程序的documents目录中时,却没有成功。 Here is my code: 这是我的代码:

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

I commented out the line: 我注释了这一行:

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

When this line is NOT commented out, and the lines above it ARE commented out: 如果此行未注释掉,并且其上方的行被注释掉:

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

NSString* documentsDirectory = [paths lastObject];

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

Then it works fine. 然后工作正常。 However, if those three lines are not commented out (as shown in the setInput method, then I get the following errors: 但是,如果没有注释掉这三行(如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

Keep in mind, this same database table is accessed and works just fine when I use the NSBundle logic. 请记住,当我使用NSBundle逻辑时,可以访问该数据库表并且可以正常工作。 I admit I don't fully understand the difference between NSBundle and documentsDirectory, but I think I would want my table to exist in my app's documents. 我承认我不完全了解NSBundle和documentsDirectory之间的区别,但我想我希望表存在于应用程序的文档中。 I would greatly appreciate any help on this. 我将不胜感激对此的任何帮助。

Thanks! 谢谢!

NSBundle is used to access resources within your application itself: that is, everything inside YourApp.app. NSBundle用于访问应用程序内部的资源:即YourApp.app内部的所有内容。 The documentsDirectory is a location outside of your app -- it's in the "home directory" which is part of your app sandbox, and which is analogous to your user home directory on the Mac. documentsDirectory是应用程序外部的位置,位于应用程序沙箱的“主目录”中,类似于Mac上的用户主目录。

These are different locations, so using one to find a file at the same subpath of another won't work. 这些位置不同,因此使用一个位置在另一个位置的同一子路径下查找文件将无效。

What @rickster is saying is this: @rickster在说什么:

  1. If you add the sqlite database to your project in Xcode, the database's file gets added to your app's bundle. 如果将sqlite数据库添加到使用Xcode的项目中,则数据库的文件将添加到应用程序的捆绑软件中。
  2. If you create the database in code, the file will (most likely) get created in your documents directory (but surely not in your bundle). 如果您使用代码创建数据库,则文件(很可能)将在您的documents目录中创建(但肯定不在您的捆绑软件中)。
  3. The two locations are completely separate. 这两个位置是完全分开的。 Your bundle is created when your app is compiled and cannot be changed later. 您的捆绑包是在您的应用编译时创建的,以后无法更改。 Your documents directory is "sandboxed", which allows you access to it; 您的文档目录为“沙盒”,使您可以访问它。 you can read/write/delete files here. 您可以在此处读取/写入/删除文件。

Copy from NSBUndle TO NSDocumentDirectory 从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];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM