首页 > 解决方案 > Xcode项目中Sqlite数据库的位置

问题描述

很抱歉重复了一个问题,尽管略有不同,但我已经尝试了一切,搜索了这个论坛和谷歌,但无法解决这个问题。我有一个 Sqlite 数据库(只有 20kb 大小),我想在使用 Xcode 的 Swift 4 项目中使用它。我已将数据库(一个 .db 文件)放在 Xcode 保存我的项目的文件夹中,但是当我运行应用程序时,我得到“没有这样的表错误”。按照调试屏幕中的文件路径将我带到一个 0kb 的文件,即空文件。我以为我已经通过使用路径名解决了这个问题(即 FileManager.default.fileExists(atPath: "/Users/...") 但它在我的 iPhone 上不起作用(仅在模拟器中)所以我走了回到尝试使用 URL 方法。我已经复制了主要代码,但我怀疑前几行有问题,或者我没有 t 将 .db 文件归档在正确的位置。我已将它添加到项目检查器中,它与作为目标的项目相关联,并显示在构建阶段屏幕的复制捆绑资源位下。我在这里真的很挣扎,所以任何帮助都非常感激。

//Function to open Cities database, add cities to array, sort alphabetically and then append "Please select city" at the start of the array
func populatePickerView() {
    let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    let databaseURL = fileURL.appendingPathComponent("Wanderer.db")
    let database = FMDatabase(path: databaseURL.absoluteString)

    guard database.open() else {
        print("Unable to open database")
        return
    }

    do {
        let cities:FMResultSet = try database.executeQuery("SELECT City from Cities", values: nil)

        while cities.next() {
            if let result = cities.string(forColumn: "City") {
                cityData.append(result)
            }
        }
    } catch {
        print("OOPS, some sort of failure")
    }

    cityData = cityData.sorted(by: <)
    cityData.insert("Please select city", at: 0)
}

标签: swiftpathdirectoryfmdb

解决方案


如果您将数据库拖放到您的 Xcode 项目结构中,并使用“如果需要,请复制项目”并选择您的目标,您的数据库位于此处:

let databaseInMainBundleURL = Bundle.main.resourceURL?.appendingPathComponent("Wanderer.db")

如果您只想读取数据,这很好,因为主包是只读的。

如果要在数据库中保存某些内容,则需要将数据库复制到文档目录。

您可以使用此功能检查您的数据库是否存在于文档目录中,并在需要时进行复制。

func copyDatabaseIfNeeded(_ database: String) {

    let fileManager = FileManager.default

    let documentsUrl = fileManager.urls(for: .documentDirectory, in: .userDomainMask)

    guard documentsUrl.count != 0 else {
        return
    }

    let finalDatabaseURL = documentsUrl.first!.appendingPathComponent("\(database).db")

    if !( (try? finalDatabaseURL.checkResourceIsReachable()) ?? false) {
        print("DB does not exist in documents folder")

        let databaseInMainBundleURL = Bundle.main.resourceURL?.appendingPathComponent("\(database).db")

        do {
            try fileManager.copyItem(atPath: (databaseInMainBundleURL?.path)!, toPath: finalDatabaseURL.path)
        } catch let error as NSError {
            print("Couldn't copy file to final location! Error:\(error.description)")
        }

    } else {
        print("Database file found at path: \(finalDatabaseURL.path)")
    }
}

并用于:

copyDatabaseIfNeeded("Wanderer")

之后,您将能够使用您的populatePickerView功能。


推荐阅读