我刚刚发现PersistentContainer创建的db的位置与UIManagedDocument创建的db不同。这是UIManagedDocument的数据库位置快照:
以下代码用于创建数据库:
let fileURL = db.fileURL // url to ".../Documents/defaultDatabase"
let fileExist = FileManager.default.fileExists(atPath: fileURL.path)
if fileExist {
let state = db.documentState
if state.contains(UIDocumentState.closed) {
db.open()
}
} else {
// Create database
db.save(to: fileURL, for:.forCreating)
}
看起来PersistentContainer 引用的数据库实际上是文件夹“StoreContent”下的文件“persistentStore”
这可以解释为什么在我的情况下,如果您想指定自定义数据库文件,PersistentContainer 无法创建数据库“defaultDatabase”,或者由于文件夹已经存在而导致崩溃。我通过像这样附加一个文件名“MyDb.sqlite”进一步验证了这一点:
let url = db.fileURL.appendingPathComponent("MyDb.sqlite")
let storeDesription = NSPersistentStoreDescription(url: url)
container.persistentStoreDescriptions = [storeDesription]
print("store description \(container.persistentStoreDescriptions)"
// store description [<NSPersistentStoreDescription: 0x60000005cc50> (type: SQLite, url: file:///Users/.../Documents/defaultDatabase/MyDb.sqlite)
container.loadPersistentStores() { ... }
这是新的 MyDb.sqlite:
根据上面的分析,如果你有这样的代码:
if #available(iOS 10.0, *) {
// load db by using PersistentContainer
...
} else {
// Fallback on UIManagedDocument method to load db
...
}
用户的设备可能在 iOS 10.0 之前,之后更新到 10+。对于此更改,我认为必须调整 url 以避免崩溃或创建新的(空)数据库(丢失数据)。