2017-10-27 1 views
0

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 ...

+0

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. –

Antwort

0

Wie Sie bereits erwähnt haben, unterscheiden sich objectIDs auf Gerät A und Gerät B. Wenn Sie wirklich einen Bezeichner vermeiden wollten Feld in Ihren Objekten können Sie ein Nachschlagen auf jedem Gerät von recordName zu objectID, aber wenn Sie Ihr Core Data Model aktualisieren Ihre Objekt-IDs ändern, so dass dieser Ansatz wäre sehr unflexibel.

Ihr Ansatz, ein ckid-Feld zu verwenden, ist korrekt, und ja, Sie müssen tatsächlich so viel Arbeit machen. CloudKit ist nur eine Transportschicht, Synchronisation zu erreichen ist ein eigenes Ding.

ich bei bestehenden Lösungen empfehlen, sich wie Ensembles, Seam oder SyncKit (von denen ich bin der Autor)

+0

danke, dass du dir die Zeit genommen hast zu antworten. Ich benutze dies als eine Möglichkeit, mir etwas fortgeschrittenere iOS-Sachen (Operationen & Nebenläufigkeit) beizubringen, da ich neu in der mobilen Entwicklung bin. Deadlocks waren mein wahrer Albtraum, aber ich bin an dem Punkt angelangt, an dem die Dinge solide und schnell laufen (Multithreading ist sowohl verwirrend als auch super cool, wenn man von einem Webentwicklungshintergrund ausgeht). Jetzt muss ich nur noch meine Fehlerbehandlung abrunden und mich vorübergehend in die Freude an meiner glänzenden neuen Sync-Engine sonnen! –

Verwandte Themen