0

を使用して 2 つのアプリ間で同じ .sqlte を共有しましたApp groups

アプリ A に録音を追加してアプリ B を開くと (最初の起動)、アプリ B は正しくデータを取得します。

アプリ A とアプリ B (バックグラウンドで既に起動されている) に記録を追加するときにデータを同期したいと思います。アプリ B はフォアグラウンドに戻ったときにデータを取得できます。

これが、アプリ 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

4

1 に答える 1

0

アプリが既にアクティブな場合は、永続ストア コーディネーターを再度設定しないでください。Xcode テンプレートで使用される標準の遅延初期化で十分であり、推奨されます。

代わりに、 をリッスンして、NSManagedObjectContextObjectsDidChangeNotification必要に応じて UI を更新することをお勧めします。

于 2015-04-16T16:53:45.023 に答える