【问题标题】:sqlite db creation issuesqlite db创建问题
【发布时间】:2011-07-03 11:43:51
【问题描述】:

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

  1. 大多数示例在应用程序中都带有 [projectName].sqlite 数据库。它是如何添加的?没有看到关于如何在项目中结束的解释。

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

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

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

默认数据库路径: /Users/myuser/Library/Application Support/iPhone Simulator/4.2/Applications/DFBAD921-CEBF-471E-B98B-04FDF2620146/Documents

默认数据库路径: /Users/myuser/Library/Application Support/iPhone Simulator/4.2/Applications/DFBAD921-CEBF-471E-B98B-04FDF2620146/Documents/mainDatabase.sqlite

可写数据库路径: /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]);
    }
}

}

期待您的回复。

【问题讨论】:

    标签: objective-c xcode ipad sqlite


    【解决方案1】:

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

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

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

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

    【讨论】:

      【解决方案2】:

      可能已经晚了,但我想回答这个问题,以便将来没有人遇到这个问题。

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

      • 点击Xcode左窗格中的sql文件

      • 在“目标成员资格”下,确保您的目标版本的“检查”已被“选中”。

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

      【讨论】:

      • 我喜欢你的帖子,谢谢伙计,它又为我节省了 30 分钟。
      【解决方案3】:

      Mac 说得很好,您使用的是 sqlite 还是核心数据?

      如果您使用的是 sqlite,那么更容易做的事情之一是在应用程序启动时,将其复制到您的应用程序文档目录中(当然,除非它已经存在,在这种情况下什么都不做)

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

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

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

      +(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);
      

      希望有帮助:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-29
        • 2020-08-29
        • 2011-06-09
        • 2012-12-21
        • 2012-03-08
        • 1970-01-01
        相关资源
        最近更新 更多