在库中使用 Swift 在 CoreData 中获取 nil managedObjectContext

Posted

技术标签:

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

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

    使用各自的数据类型创建实体 创建了 .xcdatamodeld 文件,其中包含实体 创建了一个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,我会去看看。 【参考方案1】:

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

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

需要考虑的关键事项

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

    确保您的模型文件名与NSPersistentContainer 名称匹配。 (不确定) 我将 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

【讨论】:

谢谢,但这正是我所做的。

以上是关于在库中使用 Swift 在 CoreData 中获取 nil managedObjectContext的主要内容,如果未能解决你的问题,请参考以下文章

在库中搜索 mangle

在库中使用 React 路由器 - 无法使用 useHistory()

在库中使用 fstream 时,可执行文件中出现链接器错误

在库中使用 CMake "set(XXXX CACHE ...)" 是一个错误吗?

arcgis在库中怎么搜索选中

在库中处理 Posix 信号