2016-04-12 4 views
4

Ich kann nicht mit diesem Problem umgehen, ich versuche, iCloud und Core Data in meine App zu integrieren, und ich steckte mit iCloud Synchronisation Teil.Core Data + iCloud Sync hat Speicher geändert Benachrichtigung aktualisiert nicht UI

Mein komplettes Szenario:

  1. Lokale Speicherung Kerndaten ausgesät mit Anfangsdaten
  2. Später wurde die App fragen den Benutzer über iCloud oder lokale Daten stoge
  3. Wenn Benutzer iCloud wählen, aktuelle lokale Speicherung wandert iCloud store
  4. Nach der Migration wird der Kontextkoordinator und der persistente Speicherkoordinator mit iCloud Store neu geladen.
  5. Daten aus neuem Kontext abrufen (Problem hier)

Wenn wir Diskussion über Migration wegzunehmen und den Schwerpunkt auf die Belastung persistenten Speicher Koordinator mit iCloud, denke ich, dass das Problem zu
NSPersistentStoreCoordinatorStoresDidChangeNotification Ereignis steht.

Ich verstehe es einfach nicht. In jedem Artikel, den ich gelesen habe, sah ich etwas wie: "Lade deine UI hier neu". Aber es funktioniert nicht für mich.

Reload Koordinatorfunktion

func configureContext() -> NSManagedObjectContext? { 
    // Create the coordinator and context 
    let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) 

    //remove all observers from "previous" coordinator 
    deregisterForStoreChanges() 
    //and register them for new one 
    registerObservers(persistentStoreCoordinator: coordinator) 

    do { 

     //storeSettings.url = applicationDocumentsDirectory.URLByAppendingPathComponent("iCloud.sqlite") 
     //storeSettings.options = [NSPersistentStoreUbiquitousContentNameKey:"iCloudProject"] 

     try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeSettings.url, options: storeSettings.options) 

    } catch { 
     //Here was standard error handler I didn't changed it, but removed for listing 
     abort() 
    } 
    persistentStoreCoordinator = coordinator 

    let managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) 
    managedObjectContext.persistentStoreCoordinator = coordinator 

    //not quite sure about the next string, didn't test it yet 
    managedObjectContext.mergePolicy = NSMergePolicy(mergeType:NSMergePolicyType.MergeByPropertyStoreTrumpMergePolicyType) 

    //tried to refetch my records here but, with no luck. 
    //refetchUIRecords() 
    return managedObjectContext 
} 

Und mein NSPersistentStoreCoordinatorStoresDidChangeNotification Ereignis func

func persistentStoreCoordinatorDidChangeStores(notification:NSNotification){ 

    if notification.userInfo?[NSAddedPersistentStoresKey] != nil { 
     print("-----------------------") 
     print("ADDED") 
     print("-----------------------") 
     //deduplicateRecords() 

     //if iCloud -> refetch UI 
     if NSUserDefaults.standardUserDefaults().boolForKey("iCloud"){ 
      self.createTimer() 
     } 
    } 
    print("Did Change") 

} 

Timer-Funktion erstellen ist nur eine Funktion, die für 1 secods vor der eigentlichen Erneutes Abrufen und erfrischende UI warten.

Das Problem

Wenn wir Schritt 4 von meinem Szenario zu erreichen, und configureContext Funktion aufrufen, ich dies in der Konsole sehen:

2016-04-12 13:31:27.749 TestingiCloudProject[2052:1142902] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](898): CoreData: Ubiquity: mobile~567404C0-9D84-4C07-A0F8-D25832CB65D8:iCloudProject 
Using local storage: 1 for new NSFileManager current token <ef7a917f bca47ecf 5d58862d cbe9998d 7e53e5ea> 
Did Change 
Did Change 
----------------------- 
ADDED 
----------------------- 
Timer 
Did Change 
Refetch 
Refetching... 
Number of records after fetch: 1 //must be more than 1 
2016-04-12 13:31:30.090 TestingiCloudProject[2052:1143055] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](898): CoreData: Ubiquity: mobile~567404C0-9D84-4C07-A0F8-D25832CB65D8:iCloudProject 
Using local storage: 0 for new NSFileManager current token <ef7a917f bca47ecf 5d58862d cbe9998d 7e53e5ea> 

Wie können Sie meine holen sehen Anforderung vor ausführt Using local storage: 0 und deshalb empfange ich Datensätze aus dem lokalen Speicher (1 Datensatz) nicht iCloud (die mehr als 1 enthält).

Ich verstehe nicht, wann meine Datensätze erneut abrufen. Ich nehme Timer-Teil von diesem great source für alle, die mehr über Core Data und iCloud wissen wollen. Aber 1 Sekunde ist nicht genug, 2 Sekunden ist Arbeit wie ich will, aber was, wenn iCloud Store größer sein wird als meine, oder Netzwerkverbindung wird schlimmer sein als meine, ich glaube nicht, dass Timer ist der Weg.

Ich hoffe, dass jemand schon mit diesem trivialen Problem konfrontiert ist.

EDIT

ich keine Hilfe von Apple-Entwickler-Forum und SO, so aktiviert fand meine Code-Tech-Support-Token ich, ich hoffe, sie mir helfen kann. Sobald ich mein Problem gelöst habe, werde ich eine Antwort schreiben. Aber, wenn Sie, wer diese Frage gelesen hat, die mögliche Antwort wissen, posten Sie es jetzt.

+0

ich gleiche Problem habe. Hast du jemals einen besseren Weg gefunden als einen Timer? – Josh

+1

@Josh Ich wechselte von Core Data iCloud Sync zu Core Data + CloudKit Sync. Seit Apple Notes, Reminders und andere Apps zu CloudKit umgezogen sind, denke ich, dass es ein guter Weg ist. Ich empfehle dir WWDC-Videos über CloudKit anzuschauen. Ich habe auch Probleme mit CloudKit, aber ich handle mit ihnen, Sie können einen Blick darauf werfen http://StackOverflow.com/Questions/37061665/CloudKit-ckfetchrecordchangesOperation-ckserverchangToken-and-Delda-Download –

Antwort

0

Es gibt eine weitere Benachrichtigung NSPersistentStoreDidImportUbiquitousContentChangesNotification, die vom Persistent Store Coordinator ausgelöst wird, wenn Daten aus dem allgegenwärtigen Content Store importiert werden. Hier können Sie die Änderungen mit Ihrem NSManagedObjectContext zusammenführen.

Wenn der Ubiquity-Container Änderungen von iCloud empfängt, sendet Core Data eine NSPersistentStoreDidImportUbiquitousContentChangesNotification-Benachrichtigung. Das userInfo-Wörterbuch dieser Benachrichtigung ist ähnlich aufgebaut wie das einer NSManagedObjectContextDidSaveNotification-Benachrichtigung, außer dass es NSManagedObjectID-Instanzen und nicht NSManagedObject-Instanzen enthält. Daher können Sie Änderungen von anderen Peers auf die gleiche Weise zusammenführen, wie Sie Änderungen aus anderen verwalteten Objektkontexten zusammenführen. Rufen Sie mergeChangesFromContextDidSaveNotification auf: Geben Sie in Ihrem verwalteten Objektkontext das Benachrichtigungsobjekt ein, das von Core Data gepostet wird.

https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/UsingCoreDataWithiCloudPG/UsingSQLiteStoragewithiCloud/UsingSQLiteStoragewithiCloud.html

+0

es feuert nicht für mich, aber ich habe Beobachter dafür. Ich denke, diese Benachrichtigung wird ausgelöst, wenn zwei Geräte mit iCloud und einer davon die Info ändern. Einen Moment später erhält ein anderes Gerät diese Benachrichtigung und fügt Informationen zusammen, nicht wahr? –

+0

Ja, aber die Dokumentation besagt, dass die Benachrichtigung veröffentlicht wird, nachdem Datensätze aus dem allgegenwärtigen Content Store importiert wurden, es wurde nicht nur gesagt, wenn zwei Geräte mit demselben iCloud-Account und einer davon Daten ändern, dann wird das andere Gerät benachrichtigt. –

+0

Ich habe diese Benachrichtigung leider nicht in dem von mir erwähnten Szenario erhalten. Aber wie gesagt, ich beobachte diese Benachrichtigung. –

Verwandte Themen