我正在尝试写入我创建的引号数据库。如果用户选择"最喜欢的"按钮,它将1(或真)值添加到SQLITE数据库的收藏夹列中。出于某种原因,我无法写入数据库,当我执行此代码时:
@IBAction func addFavorite(_ sender: Any) {
var configuration = Configuration()
configuration.readonly = false
let dbPath = Bundle.main.path(forResource: "data", ofType: "db")!
let dbQueue = try! DatabaseQueue(path: dbPath, configuration: configuration)
try! dbQueue.inDatabase { db in
try db.execute("""
UPDATE quotes SET favorite = 1 WHERE quote = ?;
""",
arguments: [quoteLabel.text])
}
我希望结果写入数据库并在收藏列中放置1,但遗憾的是情况并非如此。我收到这个错误:
线程1:致命错误:'尝试!'表达式意外地引发了一个错误:带有语句
UPDATE quotes SET favorite = 1 WHERE quote = ?
参数的SQLite错误8 ["禁欲是理由的强大和更清晰。"]:尝试编写只读数据库
我试过chmod 755
数据库,但也没有用。我错过了什么吗?
答案 0 :(得分:3)
数据库的路径是应用程序资源的路径。无法在iOS中修改应用资源。
有关详细信息,请参阅File System Basics。特别相关的引用:
[...]应用程序包。该目录包含应用程序及其所有资源。
您无法写入此目录。为防止篡改,bundle目录在安装时签名。写入此目录会更改签名并阻止您的应用程序启动。但是,您可以获得对应用程序包中存储的任何资源的只读访问权限。有关详细信息,请参阅Resource Programming Guide。
现在,如果无法修改数据库,您如何在数据库中写入?
好吧,你可以将它复制到你可以修改它的地方。您永远不会修改捆绑的数据库资源,只会修改副本。
再次提供文档:How do I open a database stored as a resource of my application? GRDB FAQ说:
如果应用程序应修改数据库资源,则需要将其复制到可以修改的位置。例如,在“应用程序支持”目录中。只有这样,打开一个连接:
let fileManager = FileManager.default let dbPath = try fileManager .url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true) .appendingPathComponent("db.sqlite") .path if !fileManager.fileExists(atPath: dbPath) { let dbResourcePath = Bundle.main.path(forResource: "db", ofType: "sqlite")! try fileManager.copyItem(atPath: dbResourcePath, toPath: dbPath) } let dbQueue = try DatabaseQueue(path: dbPath)