sqlite数据库创建问题

时间:2011-02-24 11:02:43

标签: objective-c xcode ipad sqlite

我正在教自己Objective-c,目前正在尝试研究如何将数据库集成到我的应用程序中。我看了很多例子,论坛和教程,但没有一个有效,我做错了什么?

  1. 大多数示例都准备好在应用程序中使用[projectName] .sqlite db。如何添加?没有看到关于如何最终在项目中的一个解释。

  2. 我已经创建了我的对象模型和类。我正在运行一个检查数据库是否存在的方法,如果没有,它会创建数据库。我发现了几个使用不同路径的例子,我不确定哪个是正确的,有些例子将我的项目文件的一部分复制到documents / mainDatabase.sqlite文件夹中!以下是否正确,如果是,为什么我会收到错误?

  3. * 由于未捕获的异常'NSInternalInconsistencyException'而终止应用程序,原因:'无法创建带有消息的可写数据库文件'无法完成操作。没有这样的文件或目录'。

    使用这些会导致上述错误,是的,defaultDBPath确实存在

    defaultDBPath: / Users / myuser / Library / Application Support / iPhone Simulator / 4.2 / Applications / DFBAD921-CEBF-471E-B98B-04FDF2620146 / Documents

    defaultDBPath: / Users / myuser / Library / Application Support / iPhone Simulator / 4.2 / Applications / DFBAD921-CEBF-471E-B98B-04FDF2620146 / Documents / mainDatabase.sqlite

    writableDBPath: / Users / myuser / Library / Application Support / iPhone Simulator / 4.2 / Applications / DFBAD921-CEBF-471E-B98B-04FDF2620146 / dbProj12.app / mainDatabase.sqlit

    - (void)createEditableCopyOfDatabaseIfNeeded {
    // First, test for existence - we don't want to wipe out a user's DB
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *documentDirectory = [self applicationDocumentsDirectory];
    NSLog(@"documentDirectory = %@", documentDirectory);
    NSString *writableDBPath = [documentDirectory stringByAppendingPathComponent:@"iBountyHunter.sqlite"];
    
    NSLog(@"defaultDBPath = %@", writableDBPath);
    BOOL dbexits = [fileManager fileExistsAtPath:writableDBPath];
    if (!dbexits) {
        // The writable database does not exist, so copy the default to the appropriate location.
        NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"iBountyHunter.sqlite"];
    
        NSLog(@"defaultDBPath = %@", defaultDBPath);
        NSError *error;
        BOOL success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
        if (!success) {
            NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
        }
    }
    

    }

    期待您的回复。

3 个答案:

答案 0 :(得分:1)

我假设您使用的是CoreData,但该解决方案对每种数据库类型都有效。

消息指出iBountyHunter.sqlite不存在,这是一个真实的消息:应该在XCode项目中添加db并在构建应用程序时打包。

某些应用程序附带了一个已填充的数据库,该数据库可能由mac上的开发人员根据在模拟器(甚至在开发设备中)中创建的内容进行修改。

  1. 在模拟器上构建并运行应用程序;
  2. 查看设备上的Documents文件夹并复制数据库;
  3. 编辑它添加自定义数据;
  4. 将数据库添加到XCode;
  5. 添加您报告的代码;
  6. 构建并让应用程序复制设备上已填充的数据库。

答案 1 :(得分:1)

可能会迟到,但我想回答这个问题,以便将来没有人能够解决这个问题。

答案与“目标会员”有关。

  • 单击Xco​​de左侧窗格中的sql文件

  • 在“目标会员资格”下,确保“检查”目标版本的“检查”。

就是这样,这解决了我的问题。我希望这对你也有帮助。

答案 2 :(得分:0)

Mac很重要,你使用的是sqlite还是核心数据?

如果您使用的是sqlite,那么最简单的方法之一就是在应用程序启动时将其复制到您的应用程序文档控制器中(除非它当然已存在,在这种情况下什么都不做)

我通常在xcode外部创建一个sqliteDB并将其添加为文件(就像图像一样)。然后在'applicationDidFinishLaunchingWithOptions'方法中(在你的app委托中我调用相同的方法,但我的代码有点不同。看看:

- (void)createEditableCopyOfDatabaseIfNeeded 
{
    //We always need to overwrite the DB, but first we need to extract usedQuestionIds, ObjectiveData and stats

    //Once database is replaced, reinsert data

    BOOL success;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"yourdatabasename.sqlite"];
    success = [fileManager fileExistsAtPath:writableDBPath];
    if (success)
    {
        //might want to check for update and if so, back up users unique data, replace database and reinsert
    }
    else
    {
        NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"yourdatabasename.sqlite"];
        [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
    }

然后在我的app委托中创建另一个方法,允许我获得一个我可以使用的数据库连接:

+(sqlite3 *)getNewDBConnection
{
    sqlite3 *newDBconnection;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *path = [documentsDirectory stringByAppendingPathComponent:@"yoursqliteDatabaseName.sqlite"];
    // Open the database. The database was prepared outside the application.
    if (sqlite3_open([path UTF8String], &newDBconnection) == SQLITE_OK) 
    {

        NSLog(@"Database opened successfully");

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

    return newDBconnection; 

}

现在,无论您在应用中的哪个位置,都可以通过以下方式与您建立连接:

sqlite3 *db = [YourAppDelegateName getNewDBConnection];

//do stuff with your sqlite db connection

sqlite3_close(db);

希望有所帮助:)