Ios swift3核心数据获取返回零

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

请参阅以下更新:

有许多类似的问题,但似乎没有一个能为我提供充分的答案,因此,任何帮助都将不胜感激

我在一个单独的应用程序中创建了一个预加载的数据库。如果这是首次运行,数据库将复制到documents目录中。 我可以从日志中看到数据库位于预期位置:

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屏幕截图。现在修复目录名。很抱歉打扰您。我在问题中更新了我的代码示例。更多的见解——或者我的代码的替代方案……将非常好。我将此标记为已解决,因为您引导我找到了问题/解决方案。我必须更加关注源代码并接收目录。再次感谢