Core-Data-cloud zu synchronisieren, benötigen Sie Hilfe mit logic
Ich bin mitten in der brainstorming-eine cloud-sync-Lösung für ein Core Data app, die ich bin derzeit in der Entwicklung. Ich Plane ein open-source-code für diese, wenn Ihre getan, für jedermann, sich mit Ihren Core-Data-apps, also input aus der community auf, wie dieses system funktionieren sollte, ist sehr willkommen 🙂 Hier ist, was ich denke:
Server-Seite
Storage-Anbieter
Wie bei allen cloud-sync-Systeme, storage ist ein wichtiges Stück des Puzzles. Es gibt viele Möglichkeiten, dies zu behandeln. Könnte ich meinen eigenen server für die Lagerung, oder verwenden Sie einen Dienst wie Amazon S3, sondern weil ich bin angefangen mit $0 Kapital, in diesem moment, eine bezahlte storage-Lösung ist nicht eine praktikable option. Nach einiger überlegung habe ich beschlossen, sich mit Dropbox (einer bereits etablierten cloud-sync-Anwendung und-Speicher-Anbieter). Die Vorteile der Verwendung von Dropbox sind:
- Es ist kostenlos (für eine begrenzte Menge an Speicherplatz)
- Darüber hinaus zu einer storage-service, es kann auch mit cloud-sync
- Sie kürzlich ein Objective-C SDK an, das macht es viel einfacher Schnittstelle in Mac-und iPhone-apps
Im Fall entscheide ich mich zu einem Wechsel auf andere storage-Anbieter in der Zukunft möchte ich hinzufügen, "services", um diese cloud-sync-framework, grundsätzlich so dass jemand, um eine service Klasse erstellt und die Schnittstelle mit Ihrer Wahl der storage-Anbieter, die können dann einfach eingesteckt werden in den Rahmen.
Storage-Struktur
Dies ist eine wirklich schwierige Teil, herauszufinden,, also ich brauche so viel input wie ich können hier. Ich habe darüber nachgedacht, eine Struktur wie diese:
CloudSyncFramework
======> [app name]
==========> devices
=============> (device id)
================> deviceinfo
================> changeset
==========> entities
=============> (entity name)
================> (object id)
Einer kurzen Erläuterung dieser Struktur:
- The master "CloudSyncFramework" (name unentschlossen) Ordner enthält separate Ordner für jede app, die das framework verwendet
- Jeder app-Ordner enthält eine Geräte - Ordner und ein Personen Ordner
- Die Geräte Ordner enthält einen Ordner für jedes Gerät, das registriert ist, mit dem Konto. Das Gerät Ordner mit dem Namen entsprechend, um die Geräte-ID, die mit so etwas wie
[[UIDevice currentDevice] uniqueIdentifier]
(auf iOS) oder eine Seriennummer (Mac OS). - Jedes Gerät Ordner enthält zwei Dateien: deviceinfo und änderungssatz. deviceinfo enthält Informationen über das Gerät (z.B. OS-version, Letzte sync Datum, Modell, etc.) und die änderungssatz Datei enthält Informationen über Objekte, die geändert wurden, seit das Gerät zuletzt synchronisiert. Beide Dateien werden einfach NSDictionaries archiviert in Dateien mit
NSKeyedArchiver
. - Jedem Core-Data-Entität hat einen Unterordner unter dem Personen Ordner
- Unter jedem entity Ordner, jedes Objekt gehört zu dieser Einheit eine separate Datei. Diese Datei enthält eine JSON-dictionary mit dem key-value-Paare.
Gleichzeitigen Sync
Dies ist einer der Bereiche, in denen bin ich fast völlig ahnungslos. Wie würde ich mit 2 Geräten verbinden und synchronisieren mit der cloud in der gleichen Zeit? Es scheint ein hohes Risiko der Dinge, die out-of-sync hier, oder sogar Beschädigung von Daten.
Umgang mit Migrationen
Wieder ahnungslos Gegend hier. , Wie würde ich damit umgehen Migrationen der Core Data verwalteten Objekt-Modell? Die einfachste Sache zu tun, hier zu sein scheint, nur um wischen Sie die cloud-Daten speichern, reinigen und laden Sie eine neue Kopie der Daten von einem Gerät, das hat sich die migration, aber das scheint mir etwas riskant, und es kann einen besseren Weg.
Client-Seite
Konvertieren NSManagedObjects in JSON
Konvertieren der Attribute in JSON ist nicht eine sehr schwierige Aufgabe (es gibt jede Menge code für die schwimmende rund um das web). Beziehungen sind das entscheidende problem. In diese stackoverflow-post, Marcus Zarra posten-code in der die Beziehung der Objekte selbst Hinzugefügt werden, um die JSON-Wörterbuch. Jedoch erwähnt er, dass dies eine unendliche Schleife verursachen, abhängig von der Struktur des Modells, und ich bin mir nicht sicher, ob dies funktionieren würde mit meiner Methode, weil ich jedes Objekt als eine einzelne Datei.
Ich habe versucht, einen Weg zu finden, um zu bekommen eine ID als string für eine NSManagedObject
. Dann konnte ich retten Beziehungen im JSON-Format als array von IDs. Die nächste Sache, die ich gefunden habe, war [[managedObject objectID] URIRepresentation]
, aber das ist nicht wirklich eine ID für ein Objekt, seine mehr einen Speicherort für das Objekt in dem persistenten Speicher, und ich weiß nicht, ob es konkret genug ist, um als Referenz für ein Objekt.
Ich glaube, ich könnte erzeugen einer UUID-Zeichenfolge für jedes Objekt und speichern Sie es als ein Attribut, aber ich bin offen für Vorschläge.
Synchronisieren von änderungen an der cloud -
Die erste (und beste) Lösung, tauchte in meinem Kopf war zu hören, für die NSManagedObjectContextObjectsDidChangeNotification
um eine Liste der geänderten Objekte, dann update/löschen/einfügen dieser Objekte in der cloud Daten speichern. Nachdem die änderungen gespeichert wurden, die ich brauchen würde, aktualisieren Sie die änderungssatz - Datei für jede andere registrierte Gerät entsprechend neu geänderten Objekte.
Einem problem, das kommt hier oben ist, wie würde ich mit einer fehlgeschlagenen oder unterbrochenen sync?. Eine Idee, die ich habe ist die erste push-änderungen in einem temporären Verzeichnis in der cloud, die dann mal, dass bestätigt wurde, als erfolgreich zu verschmelzen es mit den master-Daten auf der cloud, so dass eine Unterbrechung in der Mitte der sync nicht korrupte Daten. Dann würde ich speichern die Datensätze der Objekte, die aktualisiert werden müssen, die in der cloud in einer plist-Datei oder sowas, um die geschoben werden, während des nächsten mal, wenn die app mit dem internet verbunden ist.
Abrufen geänderten Objekte
Dies ist relativ einfach, das Gerät downloads seine änderungssatz Datei, findet heraus, welche Objekte aktualisiert werden müssen/eingefügt/gelöscht werden, verhält sich dann entsprechend.
Und fasst meine Gedanken der Logik, die dieses system verwenden 🙂 Einsichten, Anregungen, Antworten für Probleme, etc. ist stark geschätzt.
UPDATE
Nach viel denken, Lesen und TechZens Anregungen, ich habe mit einigen Modifikationen in mein Konzept.
Die größte Veränderung, die ich gedacht habe, bis zu machen, ist jedes Gerät ein separate Daten speichern in der cloud. Im wesentlichen, jedes mal, wenn die managed-object-context - spart (Dank TechZen), wird es laden Sie die änderungen an diesem Gerät, die Daten zu speichern. Nach diesen änderungen aktualisiert, es wird ein "changeset" - Datei mit den details ändern, und speichern Sie es in den änderungssatz-Ordner der ANDEREN Geräte, die mit der Anwendung. Wenn die anderen Geräte eine Verbindung zu synchronisieren, gehen Sie durch den änderungssatz-Ordner und wenden Sie jedes changeset, um die lokalen Daten zu speichern, dann aktualisieren Sie Ihre jeweiligen Daten speichert in der cloud als gut.
Nun, wenn ein neues Gerät registriert ist, mit dem account, es finden die neuesten kopieren von Daten auf allen Geräten und herunterladen, die für die Verwendung als Ihrem lokalen Speicher. Dies löst das problem der gleichzeitigen sync und reduziert die Wahrscheinlichkeit für eine Beschädigung der Daten, weil es keine "zentrale" Daten speichern, die einzelnen Geräte berührt nur seine Daten und nur updates, änderungen, anstatt bei jedem Gerät Zugriff auf und ändern die gleichen Daten zur gleichen Zeit.
Gibt es einige offensichtliche Konflikt-Situationen zu bewältigen, vor allem in Bezug auf das löschen von Objekten. Wenn ein changeset herunterladen anweisen, die app zu löschen ein Objekt, das gerade bearbeitet wird, etc. es muss Möglichkeiten zum Umgang mit diesem.
- Aktualisiert die Frage mit einigen zusätzlichen Ideen, die ich hab gedacht. Input ist willkommen 🙂
- Dies ist eine wirklich interessante Diskussion. So, drei Monate später, gibt es etwas neues hinzuzufügen? Hast du am Ende die Umsetzung dieser, wie Sie angelegt oder hast unvorhergesehenen Problemen kommen?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den Sie betrachten möchten diese pessimistische nehmen auf die cloud-Synchronisierung: Warum Cloud-Sync Wird Nie Funktionieren.
Es deckt eine Menge der Probleme, die Sie Ringen mit. Viele von Ihnen sind weitgehend unlösbar.
Es ist sehr, sehr, sehr schwierig, um Daten zu synchronisieren Zeitraum. Hinzufügen verschiedene Geräte, verschiedene Betriebssysteme, verschiedene Datenstrukturen, etc Schneebälle die Komplexität oft tödlich. Menschen, die gearbeitet haben Varianten dieses problem seit den 70er Jahren und die Dinge nicht wirklich verbessern viel.
Das grundlegende problem ist, dass, wenn Sie verlassen das system flexibel und anpassbar, und dann die Komplexität der Synchronisierung alle Variationen explodiert exponentiell als eine Funktion der Anzahl der Anpassung. Wenn du machen es steif, können Sie synchronisieren, aber Sie sind beschränkt in dem, was Sie synchronisieren können.
Wenn Sie herausfinden, dass Sie Reich sein wird. Es ist ein großes Problem für aktuelle cloud-sync-Anbieter. Sie wirkliche problem hier ist, dass Ihr nicht "synchronisieren" Ihre Verschmelzung. Software saugt bei der Zusammenführung, weil seine sehr schwer zu etablieren, die eine vordefinierte Regel festgelegt, um zu beschreiben, alle möglichen Zusammenführungen.
Das einfachste system herzustellen, ist entweder eine kanonische Geräte-oder Geräte-Hierarchie so, dass das system immer weiß, welcher Eingang zu wählen. Dies jedoch zerstört Flexibilität.
Die migration des Core-Datenmodells ist weitgehend irrelevant für die server. Das ist etwas, das Core Data verwaltet intern selbst. Modell migration updates das Modell, d.h. die entity-Graphen, nicht die tatsächlichen Daten.
Modellierung von Beziehungen ist schwer, vor allem mit tools, die nicht unterstützen, es so einfach wie Core Data nicht. Jedoch, die URI eine dauerhafte verwaltete Objekt-ID dienen soll, wie eine UUID Nägel, dass das Objekt sich zu einem bestimmten Ort in einem bestimmten laden zu einem bestimmten Gerät. Es ist technisch nicht garantiert werden universally unique, aber seine nahe genug für alle praktischen Zwecke.
Ich glaube, du bist verwirrend details der Implementierung der Core-Daten mit der cloud selbst. Wenn Sie
NSManagedObjectContextObjectsDidChangeNotification
Sie evozieren Netzwerkverkehr jedes mal, wenn die beobachteten Kontext ändert, unabhängig davon, ob diese änderungen gespeichert werden oder nicht. Abhängig von der app, das fahren konnten verbindungen tausend mal in wenigen Minuten. Stattdessen wollen Sie nur zu synchronisieren, wenn der Kontext wird gespeichert, am meisten.Sie keine änderungen übernehmen, bis der sync abgeschlossen ist. Dies ist ein großes problem und führt zu korrupten Daten. Wieder, Sie haben die Flexibilität, Komplexität und Fragilität oder mangelnde Flexibilität, Einfachheit und Robustheit.
Es ist nur einfach, wenn Sie eine starre Struktur der Daten. Beschreibung der änderungen, die eine flexible Datenstruktur ist ein Alptraum.
Nicht sicher, ob ich geholfen haben. Keines der Probleme elegante Lösungen. Die meisten designer am Ende mit Steifigkeit und/oder langsame, brute-force-iterative Verschmelzung.
Nehmen Sie sich einen ernsthaften Blick auf RestKit.
Es ist ein open-source-Projekt, das dabei helfen soll, die Integration von iOS-apps mit cloud-Daten, einschließlich, aber nicht beschränkt auf das Szenario, wo es ist ein Kern-Daten-Modell für die Daten auf dem client.
Habe ich vor kurzem begonnen, es zu benutzen in einem meiner Projekte, und fand es Recht hilfreich. In der core-data-Szenario implementieren Sie deklarativen mappings zwischen dem Datenmodell und den Inhalt ERHALTEN Sie aus und VERÖFFENTLICHEN Sie auf dem server, und es kümmert sich um Dinge wie die Injektion von Objekten aus der cloud in Ihre client-Modell, indem es neue Objekte auf dem server und Integration server-generierte Objekte-IDs in Ihren client-side-Modell, dies alles in einem hintergrund-thread und kümmert sich um alle core-data-Kontext threading-Probleme und so weiter.
RestKit keineswegs ein ausgereiftes Produkt, es hat aber eine ziemlich gute Grundlage und durchaus ein paar Dinge, die können mit der Hilfe von anderen Mitwirkenden. Vor allem, wenn Ihr Ziel ist die Erstellung einer open-source-Lösung, es wäre toll zu tragen und verbessern Sie so etwas eher als re-erfinden einer neuen Lösung. Es sei denn natürlich, Ihr sehen Sie gravierende Unterschiede zwischen dem, was Sie im Sinn haben und anderen bestehenden Lösungen 🙂
Da dieser Beitrag aktuell war, gibt es mehrere neue Optionen zur Verfügung. Es ist möglich, eine Lösung zu entwickeln, und es gibt apps Versand mit diese Lösungen.
Hier ist eine kurze Liste der wichtigsten Core-Data-sync-Optionen:
Es ist wie Apple beantwortet meine Frage, die für mich mit der Ankündigung der iCloud-SDKs, die kommt komplett mit Core Data integration. Gewinnen!