与主应用程序共享核心数据上下文的应用程序扩展编程指南

Posted

技术标签:

【中文标题】与主应用程序共享核心数据上下文的应用程序扩展编程指南【英文标题】:App Extension Programming Guide on sharing Core Data context with the main app 【发布时间】:2017-07-21 13:23:14 【问题描述】:

没有说明我们是否可以与应用扩展共享 viewContext 的文档或示例代码。

AFAK,应用程序和扩展程序在不同的进程中运行,我们不应该与另一个进程/线程共享 moc。我不应该与应用扩展共享包含应用正在使用的 viewContext。

那么我们应该创建另一个 viewContext 以在应用扩展中使用(?但 NSPersistentContainer 只提供一个 viewContext)在应用扩展中使用背景上下文(???)

当扩展程序运行时,它只与宿主应用程序直接通信。正在运行的扩展程序与其包含的应用程序之间没有直接通信;通常,包含应用程序甚至在其扩展程序运行时都没有运行。此外,包含应用程序和宿主应用程序根本不通信。

因此,由于它们都在不同的进程中运行,所以也许 (???) 我可以得出这样的结论:当应用扩展请求 viewContext 时,当包含应用程序请求 viewContext 时,2 个 viewContext(s ) 实际上是不同的实例?

class Master 
    static let shared: Master = Master()

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

    private var _backgroundContext: NSManagedObjectContext!
    var backgroundContext: NSManagedObjectContext 
        if _backgroundContext == nil 
            _backgroundContext = persistentContainer.newBackgroundContext()
        
        return _backgroundContext
    

    var viewContext: NSManagedObjectContext 
        return persistentContainer.viewContext
    

    func saveContext() 
        let context = persistentContainer.viewContext
        if context.hasChanges 
            do 
                try context.save()
             catch 
                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            
        
    

---- 更多关于如何跨进程同步数据----

1. WWDC 15:224_hd_app_extension_best_practices

此 WWDC 会议讨论如何发布通知 x 进程。

2。 NSMergePolicy

一种策略对象,用于解决托管对象的持久存储和内存版本之间的冲突。

3. WWDC 17:210_hd_whats_new_in_core_data

4. UserDefaults(suiteName: AppGroups.primary)!

【问题讨论】:

更好的方法是使用核心数据历史跟踪。 【参考方案1】:

您不能在应用和扩展程序之间共享viewContext。我不是说你不应该,我的意思是,即使你想这样做,实际上也是不可能的。应用程序及其扩展是两个独立的进程。 viewContext 对象由进程在运行时创建。应用程序无法将内存中的变量传递给 ios 上的不同进程,因此不可能在两者中使用相同的实例。您还有两个不同的持久容器对象,同样因为它们是在应用程序或扩展程序运行时创建的。

这两个容器或视图上下文很可能使用相同的持久存储文件。这并不罕见,它允许应用和扩展程序访问相同的数据。

【讨论】:

谢谢!你是一个经验丰富的程序员,不是吗?我还有一个问题,就是2个进程在同一个数据库上运行安全吗?我应该使用文件协调技术还是某种锁? (我想它是安全的,核心数据可以开箱即用地处理它)@tom-harrington 另一件事是......当发布 context-did-save 通知时,因为小部件正在保存,并且小部件和包含应用程序都使用 main-queue-type-context ,我们如何合并? 让两个进程使用同一个文件是安全的,但如果其中一个进程更改了文件,另一个进程将不会收到通知。上下文保存通知不会从一个进程传递到另一个进程。当你得到一个时,你可以在上下文对象上使用mergeChanges(fromContextDidSave:) 合并更改。 谢谢!!对于那些想了解更多关于如何在小部件和包含应用程序之间同步数据的人,请参阅 WWDC 16 224_hd_app_extension_best_practices。 只是一个小修正:App Extension Best Practices 是 WWDC 2015 的演讲,而不是 2016 年的演讲。

以上是关于与主应用程序共享核心数据上下文的应用程序扩展编程指南的主要内容,如果未能解决你的问题,请参考以下文章

在核心数据的上下文之间共享非持久对象?

什么是上下文

1009课堂小结

并发线程/进程的通信

并发编程

Java编程思想学习(十六) 并发编程