在库中使用 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的主要内容,如果未能解决你的问题,请参考以下文章
在库中使用 React 路由器 - 无法使用 useHistory()