【问题标题】:Getting nil managedObjectContext in CoreData with Swift working from a Library在库中使用 Swift 在 CoreData 中获取 nil managedObjectContext
【发布时间】:2022-01-11 09:39:32
【问题描述】:

我正在使用 Swift 5 为 iOS 开发一个库,我希望这个库独立于使用该库的应用程序使用 CoreData,这就是我到目前为止所做的:

  1. 使用各自的数据类型创建实体
  2. 创建了 .xcdatamodeld 文件,其中包含实体
  3. 创建了一个CoreDataManager,如下所示:
// MARK: - CoreDataManager
final class CoreDataManager {
    static let shared = CoreDataManager()
    private static let defaultObject = NSManagedObject.init()
    
    lazy var persistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "Audit")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()
}

问题是我试图通过以下方式获取上下文:

let coreDataManager = CoreDataManager.shared
let context = coreDataManager.persistentContainer.viewContext

context 正在返回nil

请帮忙

【问题讨论】:

  • 您对此进行过研究吗?有一些在线文章(以及此处的问题)描述了您需要采取哪些步骤来执行此操作。
  • 我已经阅读了很多文章和堆栈溢出问题,但其中大多数说我需要从 AppDelegate 获取上下文,这对我来说没有意义,因为我正在开发一个没有'没有 AppDelegate。
  • 那么我猜你读错了类型的文章,谷歌“swift core data model in package”,你应该找到一些有用的文章和SO问题
  • 谢谢@JoakimDanielson,我会去看看。

标签: swift core-data nsmanagedobjectcontext


【解决方案1】:

我解决了,显然问题是我想使用我的库的 ios 应用程序没有找到 .xcdatamodeld 文件,这导致了一个无用的 NSPersistentContainer 对象,这也意味着let context = persistentContainer.viewContext nil

为了避免以后出现此类麻烦,我将列出使用 CoreData 和 swift 库时的重要注意事项。

需要考虑的关键事项

  1. 确保使用您的库的应用知道确切的位置 去寻找它。可能想看看this article for details
  2. 如果您使用 cocoapods 来分发您的库,请确保将以下内容添加到您的 .podspec: s.resources = "path/to/model.xcdatamodeld" 这将在您的 Pod 目标中生成一个名为“Resources”的文件夹:

  1. 确保您的模型文件名与NSPersistentContainer 名称匹配。
  2. (不确定) 我将 NSManagedObjects 的类定义从
class Audit: NSManagedObject {}

public class Audit: NSManagedObject {}

即使我不确定这是否有意义,它也可以为你工作。

最后我会留下对我有用的代码

// MARK: - CoreDataManager
final class CoreDataManager {
    static let shared = CoreDataManager()
    private static let defaultObject = NSManagedObject.init()
    
    lazy var persistentContainer: NSPersistentContainer? = {
        let modelURL = Bundle(for: Audit.self).url(forResource: "Audit", withExtension: "momd")
        
        guard let model = modelURL.flatMap(NSManagedObjectModel.init) else {
            print("Fail to load the trigger model!")
            return nil
        }
        
        let container = NSPersistentContainer(name: "Audit", managedObjectModel: model)
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        
        return container
    }()
}

并获取外部上下文

let coreDataManager = CoreDataManager.shared

guard
    let context = coreDataManager.persistentContainer?.viewContext
else {
    print("Nil context case")
    return
}

希望对大家有所帮助!!

【讨论】:

  • 关于第 4 点,如果您想从图书馆外部访问课程,则需要这个
【解决方案2】:

您可以尝试在 AppDelegate 中定义此范围:

lazy var persistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "Audit")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()

然后像这样在你的 CoreDataManager 文件中使用它:

class CoreDataManager: NSObject {
    
    static let shared = CoreDataManager()
    
    let managedContext = _appDelegator.persistentContainer.viewContext //Here _appDelegator is the object to your AppDelegate class
}

【讨论】:

  • 谢谢,但这正是我所做的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多