Ios swift3核心数据获取返回零
请参阅以下更新: 有许多类似的问题,但似乎没有一个能为我提供充分的答案,因此,任何帮助都将不胜感激 我在一个单独的应用程序中创建了一个预加载的数据库。如果这是首次运行,数据库将复制到documents目录中。 我可以从日志中看到数据库位于预期位置:Ios swift3核心数据获取返回零,ios,swift,core-data,Ios,Swift,Core Data,请参阅以下更新: 有许多类似的问题,但似乎没有一个能为我提供充分的答案,因此,任何帮助都将不胜感激 我在一个单独的应用程序中创建了一个预加载的数据库。如果这是首次运行,数据库将复制到documents目录中。 我可以从日志中看到数据库位于预期位置: AppDelegate urls: [file:///Volumes/HD1%20-%20DATA/Users/david/Library/Developer/CoreSimulator/Devices/8B0E16F5-B739-4299-9B4
AppDelegate urls: [file:///Volumes/HD1%20-%20DATA/Users/david/Library/Developer/CoreSimulator/Devices/8B0E16F5-B739-4299-9B4D-E6A3C8C92E55/data/Containers/Data/Application/B8A87853-6FEB-4532-83EF-AB08985F2B43/Documents/]
通过使用SQLItemManager,我可以验证数据库是否按预期保存了数据
我的CoreData对象图是:
但是,当我执行一个获取请求时,结果是nil
这是提取请求:
func testLetters() {
print(#function)
let moc = coreDataStack.persistentContainer.viewContext
let letterFetch = NSFetchRequest<NSFetchRequestResult>(entityName: "LetterEntity")
do {
let fetchedLetters = try moc.fetch(letterFetch) as! [LetterEntity]
print(#function, "letter: ", fetchedLetters)
} catch {
fatalError("Failed to fetch employees: \(error)")
}
}
同样,欢迎任何帮助
更新:我已将数据库副本更改如下:
import UIKit
import CoreData
class CoreDataStack {
static let instance = CoreDataStack()
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "GuessGreek")
let directoryUrls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let applicationDocumentDirectory = directoryUrls[0]
let storeUrl = applicationDocumentDirectory.appendingPathComponent("GuessGreek.sqlite")
container.loadPersistentStores(completionHandler: { (storeUrl, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
func saveContext() {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch let error as NSError {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
}
}
let directoryUrls = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)
let applicationDocumentDirectory = directoryUrls[0]
let managedContext = coreDataStack.persistentContainer.viewContext
let storeUrl = applicationDocumentDirectory.appendingPathComponent("GuessGreek.sqlite")
print("AppDelegate", #function, "StoreURL", storeUrl)
if !FileManager.default.fileExists(atPath: (storeUrl.path)) {
print("Copying databases...")
let sourceSqliteURLs = [
Bundle.main.url(forResource: "GuessGreekDatabase", withExtension: "sqlite")!,
Bundle.main.url(forResource: "GuessGreekDatabase", withExtension: "sqlite-wal")!,
Bundle.main.url(forResource: "GuessGreekDatabase", withExtension: "sqlite-shm")!]
let destSqliteURLs = [
applicationDocumentDirectory.appendingPathComponent("GuessGreek.sqlite"),
applicationDocumentDirectory.appendingPathComponent("GuessGreek.sqlite-wal"),
applicationDocumentDirectory.appendingPathComponent("GuessGreek.sqlite-shm")]
for index in 0..<sourceSqliteURLs.count {
do {
try FileManager.default.copyItem(at: sourceSqliteURLs[index], to: destSqliteURLs[index])
print(#function, "Done copying")
} catch {
print(error)
}
do {
try managedContext.save()
} catch let error as NSError {
print("Error While Saving Data: \(error.userInfo)")
}
}
}
让directoryURL=FileManager.default.URL(用于:.applicationSupportDirectory,位于:.userDomainMask中)
让applicationDocumentDirectory=DirectoryURL[0]
让managedContext=coreDataStack.persistentContainer.viewContext
让storeUrl=applicationDocumentDirectory.appendingPathComponent(“GuessGreek.sqlite”)
打印(“AppDelegate”、#函数、“StoreURL”、StoreURL)
如果FileManager.default.fileExists(atPath:(storeUrl.path)){
打印(“复制数据库…”)
让sourceSqliteURLs=[
Bundle.main.url(用于资源:“GuessGreekDatabase”,扩展名为:“sqlite”)!,
Bundle.main.url(用于资源:“GuessGreekDatabase”,扩展名为:“sqlite wal”)!,
Bundle.main.url(用于资源:“GuessGreekDatabase”,扩展名为:“sqlite shm”)!]
让destSqliteURLs=[
applicationDocumentDirectory.appendingPathComponent(“GuessGreek.sqlite”),
applicationDocumentDirectory.appendingPathComponent(“GuessGreek.sqlite wal”),
applicationDocumentDirectory.appendingPathComponent(“GuessGreek.sqlite shm”)]
对于0中的索引,默认情况下,NSPersistentContainer使用应用程序支持目录,而不是文档目录
如果在loadPersistentStores完成块中打印storeURL的值,您将看到它指向应用程序支持。发生的情况是,它正在基于您的模型创建一个空白数据库,而忽略您所做的副本
如果要控制nspersistentcainer
在何处工作,请改为复制到应用程序支持,或者传入一个带有指向文档目录的URL的nspersistentcoredescription
对象
值得注意的是,以下几行:
let directoryUrls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let applicationDocumentDirectory = directoryUrls[0]
let storeUrl = applicationDocumentDirectory.appendingPathComponent("GuessGreek.sqlite")
在您当前的代码中完全不做任何事情
同样值得注意的是,您的SqlItemManager屏幕截图显示该文件名为GuessGreekDatabase.sqlite
,但您的NSPersistentContainer将默认存储名为GuessGreek.sqlite
,因此可能还需要修复,除非您在复制过程中这样做。谢谢!!我已经用正确的SQLiteMan更新了我的问题AGR屏幕截图。现在修复目录名。很抱歉打扰您。我在问题中更新了我的代码示例。更多的见解——或者我的代码的替代方案……将非常好。我将此标记为已解决,因为您引导我找到了问题/解决方案。我必须更加关注源代码并接收目录。再次感谢