TLDR Version: Wie funktioniert meine app wissen, dass ein Coredata-Objekt auf dem Gerät A, ein Coredata-Objekt auf dem Gerät B und ein CKRecord in Wolkenjungen ist alle gleich Rekord?Syncing Beziehungen mit Coredata und Wolkenjungen
ausführliche Version:
Ich arbeite an einer Anwendung, die Coredata lokal und Wolkenjungen Synchronisierung zwischen den Geräten verwendet. Ich verstehe nicht, wie CoreData-Beziehungen und CloudKit-Referenzen zusammenarbeiten sollen, sobald Sie mehrere Geräte hinzufügen.
Einige Wahrheiten, wie ich sie verstehe:
1) Wenn Sie ein Coredata-Objekt erstellen, es ein objectID zugewiesen bekommt. Sie können bei der Erstellung nicht selbst eine zuweisen oder eine bereits existierende ändern. Aus dem Beziehungsfeld CoreData können Sie direkt auf die zugehörigen Objekte zugreifen oder Sie können die Objekt-ID dieser verwandten Objekte mit einer Komfortmethode erhalten.
2) Wenn Sie einen CloudKit-Datensatz erstellen, können Sie ihm einen Datensatznamen (im Grunde das CloudKit-Äquivalent einer CoreData-Objekt-ID) zuweisen oder er wird standardmäßig generiert. Ein CloudKit-Referenzfeld enthält eine Zeichenfolge, die den Datensatznamen des verknüpften Datensatzes darstellt.
Also hier ist, wie mein App funktioniert (und funktioniert nicht)
Gerät A zum ersten Mal startet. CoreData instanziiert eine Reihe von Standardobjekten, die der Benutzer bei der Verwendung der App bearbeiten (oder hinzufügen/löschen) kann. Wenn die Einrichtung abgeschlossen ist und die App feststellt, dass alles läuft, wird eine Synchronisierung mit CloudKit durchgeführt. Es sucht zuerst nach bereits vorhandenen Datensätzen (keine) und lädt neue Datensätze in CloudKit, wobei die CoreData-Objekt-IDs als CloudKit-Datensatznamen verwendet werden. Die Objekt-IDs auf Gerät A und die CloudKit-Datensatznamen sind also identisch. Zwischen diesen verschiedenen Objekten bestehen mehrere Beziehungen. So weit, so gut - dieser Teil funktioniert (Änderungen im Dashboard aktualisieren Beziehungen in Coredata korrekt und umgekehrt).
Die Dinge gehen jetzt von den Schienen als Gerät B zum ersten Mal startet. CoreData instanziiert die gleiche Gruppe von Standardobjekten (mit eindeutigen Objekt-IDs), die der Benutzer dann ändern oder hinzufügen/löschen kann, wenn er die App verwendet. Wenn die Einrichtung abgeschlossen ist und alles möglich ist, wird eine Synchronisierung mit CloudKit durchgeführt. Es zieht alle vorhandenen Datensätze aus CloudKit herunter und aktualisiert die übereinstimmenden lokalen Datensätze. Passender wird nie passieren basierend auf recordName < -> objectIDs, weil Gerät B eindeutige objectIDs hat. Hier kommt mein Verständnis zu kurz.
Meine aktuelle versuchte Lösung
Meine Lösung ist derzeit eine benutzerdefinierte CKID Feld sowohl Coredata Entitäten und Wolkenjunge Datensätze hinzuzufügen. Bei der ersten Synchronisierung auf jedem Gerät versucht dieses Feld entsprechend zu synchronisieren. Wenn Datensätze in CloudKit vorhanden sind, durchläuft es diese und versucht, basierend auf den benutzerdefinierten Feldern und dem Entitätstyp vorhandene CoreData-Objekte mit diesen CloudKit-Datensätzen abzugleichen - beispielsweise das Feld "Name" einer Entität. Wenn es eine Übereinstimmung findet, aktualisiert es das ckid-Feld lokal. Wenn keine gefunden wird, wird ein neues CoreData-Objekt erstellt. Dieses ckid-Feld wird immer dann verwendet, wenn die App nach einer CoreData-Beziehung sucht oder eine CKReference erstellt. Alles in allem fühlt es sich an, als würde ich viel arbeiten, was ich nicht tun sollte.
Vielen Dank im Voraus für jede Hilfe!
UPDATE 11/3/17
Eine Woche später und insgesamt scheint sicher, dass der falsch Weg zu sein, um die Synchronisation zwischen den Geräten zu gehen. Mein benutzerdefiniertes ID-Feld ist nicht mehr synchron und verursacht alle Arten von Chaos.
Ich glaube weiterhin, dass ich hier etwas sehr Grundlegendes verpasse. Wie verhält sich ein Datensatz an einem anderen Ort? Wenn es möglich wäre, eine vorhandene CoreData-Objekt-ID zu ändern (oder bei der Erstellung eine zu vergeben), wäre das einfach - was fehlt mir?!? Was ich mache, fühlt sich jetzt sehr falsch an, aber ich weiß nicht, was ich sonst noch versuchen soll ...
TLDR Version: Sie können den Primärschlüssel von Coredata-Objekt als auf recordWolkenJunge verwenden und Karte diese um Identität zu überprüfen. –