【问题标题】:Where would you place your SQLite database file in an iPhone app?您会将 SQLite 数据库文件放在 iPhone 应用程序的什么位置?
【发布时间】:2010-10-17 13:20:59
【问题描述】:

当我最初为我的应用程序创建一个带有预插入数据集的 SQLite 数据库文件时,我必须将此文件放在我的 Xcode 项目中的某个位置,以便它转到我的 iPhone 应用程序。我想“资源”是合适的地方。

在 iPhone 应用程序中部署 SQLite 数据库文件的基本“步骤”是什么?

  • 手动创建数据库
  • 将数据库文件添加到项目中(在哪里?)

我目前正在阅读整个 SQLite 文档,虽然这与 iPhone 的关系不大。

【问题讨论】:

    标签: iphone sqlite


    【解决方案1】:

    您需要先将 SQLite 文件添加到您的 Xcode 项目中 - 最合适的位置是在资源文件夹中。

    然后在您的应用程序委托代码文件中,在 appDidFinishLaunching 方法中,您需要首先检查是否已创建 SQLite 文件的可写副本 - 即:已在用户文档中创建 SQLite 文件的副本iPhone 文件系统上的文件夹。如果是,你什么都不做(否则你会用默认的 Xcode SQLite 副本覆盖它)

    如果不是,则将 SQLite 文件复制到那里 - 使其可写。

    请参阅以下代码示例以执行此操作:这取自 Apple 的 SQLite 书籍代码示例,其中此方法从应用程序委托 appDidFinishLaunching 方法调用。

    // Creates a writable copy of the bundled default database in the application Documents directory.
    - (void)createEditableCopyOfDatabaseIfNeeded {
        // First, test for existence.
        BOOL success;
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSError *error;
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"bookdb.sql"];
        success = [fileManager fileExistsAtPath:writableDBPath];
        if (success)
            return;
        // The writable database does not exist, so copy the default to the appropriate location.
        NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"bookdb.sql"];
        success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
        if (!success) {
            NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
        }
    }
    

    ============

    这是 Swift 2.0+ 中的上述代码

    // Creates a writable copy of the bundled default database in the application Documents directory.
    private func createEditableCopyOfDatabaseIfNeeded() -> Void
    {
        // First, test for existence.
        let fileManager: NSFileManager = NSFileManager.defaultManager();
        let paths:NSArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
        let documentsDirectory:NSString = paths.objectAtIndex(0) as! NSString;
        let writableDBPath:String = documentsDirectory.stringByAppendingPathComponent("bookdb.sql");
    
        if (fileManager.fileExistsAtPath(writableDBPath) == true)
        {
            return
        }
        else // The writable database does not exist, so copy the default to the appropriate location.
        {
            let defaultDBPath = NSBundle.mainBundle().pathForResource("bookdb", ofType: "sql")!
    
            do
            {
                try fileManager.copyItemAtPath(defaultDBPath, toPath: writableDBPath)
            }
            catch let unknownError
            {
                print("Failed to create writable database file with unknown error: \(unknownError)")
            }
        }
    }
    

    【讨论】:

    • 如果要在数据库上写,应该在哪里?我知道如果它在资源组(主捆绑包)中,它是只读的,那么这是允许写入和读取的正确方法吗?谢谢!
    • 我知道这有点晚了,但是我将如何查找它是否需要从主包更新?我尝试检查文件属性,但是每当我编译新版本时,应用程序中文件的修改日期都会发生变化。
    • 我已经在我的一个视图控制器中打开了数据库文件,我在我的表中插入了值,然后再次在另一个视图控制器中打开它,我在这里检索值我得到了未知错误。它是在创建我的数据库的另一个实例吗?
    • 为什么你的数据库名称有 .sql 扩展名?
    【解决方案2】:

    如果您只是要查询数据,您应该可以将其留在主包中。

    但是,这可能不是一个好习惯。如果您将来要扩展您的应用程序以允许写入数据库,则您必须重新解决所有问题...

    【讨论】:

    • @Willi 不一定是真的。如果他将来要扩展他的应用程序,他总是可以在更新中添加上述功能。应该无缝工作。
    猜你喜欢
    • 2016-09-16
    • 1970-01-01
    • 1970-01-01
    • 2012-03-03
    • 2016-10-12
    • 1970-01-01
    • 2011-01-03
    • 2011-09-17
    • 1970-01-01
    相关资源
    最近更新 更多