将核心数据堆栈更新为 applicationWillEnterForeground

Update Core Data Stack into applicationWillEnterForeground

我在 App groups 的两个应用程序之间共享了相同的 .sqilte。

当我在应用程序 A 中添加录音并打开应用程序 B(首次启动)时,应用程序 B 正确检索数据。

我想在应用A和应用B(已在后台启动)中添加录音时同步数据,应用B回到前台时可以检索数据。

这就是为什么当 App B 回到前台时,我将 Core Data Sack 更新为 applicationWillEnterForeground。哪种方式是正确的?

let directory = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.com.sl.sharedData");

        let url = directory?.URLByAppendingPathComponent("sharedData.sqlite")
        let store = self.persistentStoreCoordinator?.persistentStoreForURL(url!)
        var error : NSError?
        if false == self.persistentStoreCoordinator?.removePersistentStore(store!, error: &error)
        {
            println("error = \(error!.localizedDescription)")
            return
        }
        let options = [
            NSMigratePersistentStoresAutomaticallyOption: true,
            NSInferMappingModelAutomaticallyOption: true,
            // Adding the journalling mode recommended by apple
            NSSQLitePragmasOption: ["journal_mode": "DELETE"]
        ]
        var failureReason = "There was an error creating or loading the application's saved data."
        if self.persistentStoreCoordinator?.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: options, error: &error) == nil {
            // Report any error we got.
            var dict = [String: AnyObject]()
            dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
            dict[NSLocalizedFailureReasonErrorKey] = failureReason
            dict[NSUnderlyingErrorKey] = error
            error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
            // Replace this with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            NSLog("Unresolved error \(error), \(error!.userInfo)")
            abort()
        }
        _persistentStoreCoordinator = nil
        _managedObjectContext = nil
        let rootViewController = self.window!.rootViewController as ViewController
        rootViewController.context = self.managedObjectContext

不幸的是,它没有像我想要的那样工作。当我进入 applicationWillEnterForeground 时,检索到的数据每次都会被配音。哪种方式是正确的?

// 编辑 2014/04/17:尝试使用 Mundi 的解决方案

我试过 NSManagedObjectContextObjectsDidChangeNotification

   func applicationWillEnterForeground(application: UIApplication) {

        NSNotificationCenter.defaultCenter().addObserver(
            self,
            selector: "mergeContextChangesForNotification:",
            name: NSManagedObjectContextObjectsDidChangeNotification,
            object: managedObjectContext)

        let rootViewController = self.window!.rootViewController as ViewController
        rootViewController.context = managedObjectContext
        }
    }

func mergeContextChangesForNotification(notification : NSNotification){
        let otherContext: NSManagedObjectContext = notification.object as NSManagedObjectContext

        if((otherContext != managedObjectContext) && (otherContext.persistentStoreCoordinator == managedObjectContext.persistentStoreCoordinator)){

            managedObjectContext.performBlockAndWait{ () -> Void in

                self.managedObjectContext.mergeChangesFromContextDidSaveNotification(notification)
            }
        }
    }

mergeContextChangesForNotification 已调用,但我从未进入过这种情况:if otherContext != managedObjectContext) && (otherContext.persistentStoreCoordinator == managedObjectContext.persistentStoreCoordinator

如果应用程序已经处于活动状态,则不应再次设置持久性商店协调器。 Xcode 模板中使用的标准惰性初始化就足够了,而且更可取。

相反,您可能想要收听 NSManagedObjectContextObjectsDidChangeNotification 并根据需要更新您的 UI。