我正在使用FMDatabase库来使用预备数据库sqlite。
我收到了这个错误:
Error Domain=FMDatabase Code=8 "attempt to write a readonly database" UserInfo={NSLocalizedDescription=attempt to write a readonly database}
2017-10-27 19:59:10.983238+0330 kashanmap[417:63718] Unknown error calling sqlite3_step (8: attempt to write a readonly database) eu
2017-10-27 19:59:10.983473+0330 kashanmap[417:63718] DB Query: insert into LocationInfoFa
这是我的班级:
import FMDB
class DatabaseManager {
private let dbFileName = "kashanmapDB_upgrade_3-4.db"
private var database:FMDatabase!
let TABLE_LOCATION_FA = "LocationInfoFa";
let TABLE_LOCATION_EN = "LocationInfoEn";
let TABLE_GREAT_PEOPLE_FA = "GreatPeopleInfoFa";
let TABLE_GREAT_PEOPLE_EN = "GreatPeopleInfoEn";
let TABLE_TAGS = "Tags";
let TABLE_RELATION_TAG_LOCATION = "RelationTagLocation";
let TABLE_NECESSARY_INFORMATION = "NecessaryInformation";
let TABLE_SLIDER_FA = "SliderFa";
let TABLE_SLIDER_EN = "SliderEn";
let DATABASE_VERSION = 4;
static var LANGUAGE = 1 ; //1:Fa , 2:En
var utilities = Utilities()
init() {
openDatabase()
if(utilities.getData(key: "lang") == "2")
{
DatabaseManager.LANGUAGE = 2
}
}
func openDatabase() {
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let dbPath = URL(fileURLWithPath: paths).appendingPathComponent(dbFileName)
let str_path = Bundle.main.resourceURL!.appendingPathComponent(dbFileName).path
let database = FMDatabase(path: str_path)
/* Open database read-only. */
if (!(database.open(withFlags: 2))) {
print("Could not open database at \(dbPath).")
} else {
print("opened database")
self.database = database;
}
}
func closeDatabase() {
if (database != nil) {
database.close()
}
}
我的数据库路径:
我的疑问:
do {
let db = database
let q = try db?.executeUpdate("insert into \(table) (catid,subcat_id,id,subcat_title,title,description,lat,lon,takhfif,images,wifi,apple_health,wc,full_time,pos,work_hours,phone,mobile,fax,website,email,address,facebook,instagram,linkedin,telegram,googleplus,twitter,publish,feature,manager,city,rating_sum,rate_count,lastip,parking,isMallID,mallID,discount_images,price_images,newProduct_images,services_images,order_online,out_upon,cat_title,cat_icon,last_modify,item_logo,cat_logo,rate_sum1,rate_sum2,rate_sum3,rate_count1,rate_count2,rate_count3,rate_title1,rate_title2,rate_title3,rate_enable,installments_text,installments_image) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", values:[ catid,subcat_id,id,subcat_title,title,description,lat,lon,takhfif,images,wifi,apple_health,wc,full_time,pos,work_hours,phone,mobile,fax,website,email,address,facebook,instagram,linkedin,telegram,googleplus,twitter,publish,feature,manager,city,rating_sum,rate_count,lastip,parking,isMallID,mallID,discount_images,price_images,newProduct_images,services_images,order_online,out_upon,cat_title,cat_icon,last_modify,item_logo,cat_logo,rate_sum1,rate_sum2,rate_sum3,rate_count1,rate_count2,rate_count3,rate_title1,rate_title2,rate_title3,rate_enable,installments_text,installments_image])
} catch {
print("\(error)")
}
堆栈溢出有一些解决方案,但它们不被接受为真正的答案。
updated2
我收到了这个错误:
DB does not exist in documents folder
我的代码:
init() {
openDatabase()
if(utilities.getData(key: "lang") == "2")
{
DatabaseManager.LANGUAGE = 2
}
}
func copyDatabaseIfNeeded() {
// Move database file from bundle to documents folder
let fileManager = FileManager.default
let documentsUrl = fileManager.urls(for: .documentDirectory,
in: .userDomainMask)
guard documentsUrl.count != 0 else {
return // Could not find documents URL
}
let finalDatabaseURL = documentsUrl.first!.appendingPathComponent("kashanmapDB_upgrade_3-4.db")
if !( (try? finalDatabaseURL.checkResourceIsReachable()) ?? false) {
print("DB does not exist in documents folder")
let documentsURL = Bundle.main.resourceURL?.appendingPathComponent("kashanmapDB_upgrade_3-4.db")
do {
try fileManager.copyItem(atPath: (documentsURL?.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)")
}
}
func openDatabase() {
self.copyDatabaseIfNeeded()
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let dbPath = URL(fileURLWithPath: paths).appendingPathComponent(dbFileName)
let str_path = Bundle.main.resourceURL!.appendingPathComponent(dbFileName).path
let database = FMDatabase(path: str_path)
/* Open database read-only. */
if (!(database.open(withFlags: 2))) {
print("Could not open database at \(dbPath).")
} else {
print("opened database")
self.database = database;
}
}
答案 0 :(得分:0)
您正面临此错误,因为您正尝试在捆绑目录中编写(更新) .db 文件,该目录不允许:
<强> AppName.app:强>
这是应用程序的捆绑包。该目录包含应用程序和所有 它的资源。 您无法写入此目录。阻止 篡改,bundle目录在安装时签名。 写入此目录会更改签名并阻止您的应用程序 从发射。但是,您可以获得对任何的只读访问权限 应用包中存储的资源。
<子> File System Basics - Table 1-1: Commonly used directories of an iOS app 子>
如果您的目标是更新文件,您应该实现复制的逻辑 - 如果它尚未被复制到文档中目录,因此您可以使用复制的文件读/写事务。
备注对于iOS 11及更高版本,您可能希望将数据库文件复制到 Application Support 目录中,如果您不想让我们看到它们通过 Files iOS应用导航到您的应用时最终用户。有关详细信息,请查看iOS Storage Best Practices Apple视频会话。
您注意到此逻辑应该应用于应用主程序包中的任何文件,例如它也是applicable for JSON files。