Core Data exportieren / importieren (z. B. JSON)

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Rabattcode für die heise MacDev 2020: Macoun20

    Aufgrund der Corona-Krise: Die Veröffentlichung von Stellenangeboten und -gesuchen ist bis 31.12.2020 kostenfrei. Das beinhaltet auch Angebote und Gesuche von und für Freischaffende und Selbstständige.

    • Core Data exportieren / importieren (z. B. JSON)

      Hallo zusammen,

      bitte entschuldigt den Roman, ich brauche Hilfe, meine Gedanken zu ordnen :)

      Ich muss auf ein Thema zurück kommen, dass ich hier vor vier Jahren (huch!) schon einmal angesprochen habe: Es geht darum, Teile eines NSPersistentStores zu exportieren, um z. B. ein Sharen per Mail zu ermöglichen. Seinerzeit hatte ich ein vergleichsweise simples Datenmodell und meine Umsetzung läuft seitdem problemlos. Allerdings gab es auch nur überschaubare Relationen. Nun ist es etwas komplizierter und mir ist nicht klar, wie ich die Sache am besten realisiere.

      Es geht um eine Art Produkt-Verwaltung
      • Ein Shop hat mehrere Produkte (one-to-many)
      • Ein Produkt hat verschiedene Eigenschaften, manche davon aus Picklisten auswählbar, z. B. Größe oder Farbe (many-to-one)
      • Produktlisten ("Abfragen") beinhalten Selektionskriterien, die den Produkt-Eigenschaften entspricht (und auch obige Picklisten nutzen); so kann eine Liste z. B. alle grünen oder roten Produkte beinhalten (many-to-many)
      Die Beziehungen sehen also (auszugsweise) so aus:

      Shop <--->> Produkt <<---> Farbe
      Shop <--->> Liste <<--->> Farbe

      Nach meinem Verständnis muss ich beim Exportieren der Relationen einen eindeutigen Schlüssel des Zielobjektes speichern. Nur dann kann ich später beim Importieren die Referenzen wieder herstellen. Ohne einem solchen kann ich z. B. bei der Farbe eines zweiten Produktes nicht bestimmen, ob es sich um eine neue oder bereits vorher importierte Farbe handelt. Beim letzten Mal hatte ich einen eindeutigen Schlüssel im Datenmodell, jetzt müsste ich einen z. B. auf Basis der objectID erzeugen:
      1. Ich würde also beim Exportieren eines Shops alle Artikel und ausgehend von diesen alle (verwendeten) Einträge der Picklisten exportieren, also z. B. alle benutzen Farben; hierbei speichere ich mit dem Artikel eindeutige IDs der jeweiligen Farbe (und die Farbe extra als eigene Entität)
      2. Dann exportiere ich alle Produktlisten und auf diesem Wege wieder Farben - eventuelle neue (nicht von Artikeln verwendete); hierbei speichere ich mit der Produktliste wieder eindeutige IDs der verwendeten Farben.
      3. Beim Import lege ich die Farben an und erstelle dann die Referenzen.
      Beim letzte Schritt habe ich einen Knoten im Kopf: Wie setze ich eine saubere Referenz, wenn z. B. ein zweiter Artikel die Farbe Rot hat, ohne die im Export genutzte ID auch im Core Data Schema zu haben? Die objectID wird ja eine neue...

      Ich habe das Gefühl, unnötig kompliziert zu denken und mein Google-fu versagt: Ich finde zwar z. B. viele SO-Artikel, werde aber aus den Implementierungen nicht wirklich schlau. Auf GitHub findet sich auch einiges - diese Lösung fand ich recht vielversprechend - aber das Thema der Relationen bleibt mir immer noch rätselhaft.

      Wie löst Ihr dieses (doch sehr allgemeine) Problem? Wo habe ich einen Knoten im Gehirn? Lohnt sich Selberbauen oder gibt es hierfür Quasi-Standardlösungen?

      Vielen Dank für's Mitdenken, Mattes
      Diese Seite bleibt aus technischen Gründen unbedruckt.
    • wenn ich das jetzt richtig verstanden habe, dann hast du im Moment eine separate Liste mit Farben und deren ids verwendest du dann im Objekt? Das würde ich nicht machen. Das sind redundante und sehr Fehleranfälligkeit Informationen. Wenn du die Liste der Farben brauchst, dann hole sie dir halt eben mit einem query aus allen Produkten.
      2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

      Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
    • Dann habe ich mich vielleicht undeutlich ausgedrückt. Das Datenmodell hat keine Redundanzen. Es gibt (auszugsweise) die Entitäten
      • Shop
      • Artikel
      • Farbe
      • Produktliste
      Diese sind mit den oben skizzierten Beziehungen verknüpft.

      Die ID brachte ich nur in's Spiel, weil mir sonst unklar ist, wie ein Export wieder in Core Data als NSManagedObjects importiert werden kann:

      Angenommen, beim Import des ersten Artikels wird das Objekt "Rot" der Farb-Entität referenziert. Nun wird der zweite, ebenfalls rote Artikel importiert. Woher weiss ich - ohne einem Schlüssel, der das Rot-Objekt eindeutig identifiziert - dass es sich im das gleiche Objekt handelt? Ohne diese Information würde ich nicht das bereits bestehende Rot-Objekt im zweiten Artikel referenzieren, sondern ein neues (doppeltes) Rot anlegen und verwenden.

      Seinerzeit hatte ich im Datenmodell einen eindeutigen Schlüssel. Dann habe ich vor Erzeugen eines Objektes beim Import prüfen können, ob dieses schon vorhanden war. Wenn ja, habe ich das bestehende Objekt referenziert.

      Ich sehe momentan keinen anderen Weg, als einen solchen eindeutigen Schlüssel in's Core Data Schema aufzunehmen, die objectID ist aus dem oben genannten Grund (sie ändert sich beim Erzeugen eines neuen Objektes) ungeeignet.

      Was übersehe ich?

      Mattes
      Diese Seite bleibt aus technischen Gründen unbedruckt.
    • MyMattes schrieb:

      Dann habe ich mich vielleicht undeutlich ausgedrückt. Das Datenmodell hat keine Redundanzen. Es gibt (auszugsweise) die Entitäten
      • Shop
      • Artikel
      • Farbe
      • Produktliste
      Diese sind mit den oben skizzierten Beziehungen verknüpft.

      Die ID brachte ich nur in's Spiel, weil mir sonst unklar ist, wie ein Export wieder in Core Data als NSManagedObjects importiert werden kann:

      ...

      Seinerzeit hatte ich im Datenmodell einen eindeutigen Schlüssel. Dann habe ich vor Erzeugen eines Objektes beim Import prüfen können, ob dieses schon vorhanden war. Wenn ja, habe ich das bestehende Objekt referenziert.

      Ich sehe momentan keinen anderen Weg, als einen solchen eindeutigen Schlüssel in's Core Data Schema aufzunehmen, die objectID ist aus dem oben genannten Grund (sie ändert sich beim Erzeugen eines neuen Objektes) ungeeignet.

      Was übersehe ich?

      Mattes
      Hallo Mattes,

      ich bin nun nicht der Profi was den NSPersistentStores angeht, aber vor kurzen hatte ich ein ähnlich gelagertes Problem. Im Grunde hast Du die Lösung schon selbst benannt - eigene Primary-, Forgeinkeys in den Tabellen einsetzen und die Beziehungen dahingehend aktualisieren. Ansonsten müsstest Du in der Importfunktion die Daten einer Plausibilitätsprüfung unterziehen, bevor diese dem DBS hinzugefügt werden. Je nachdem wie komplex die Relationen sind, ist dieser Weg sehr aufwendig und mitunter fehlerbehaftet.

      Bedenke die Auswertung der Relationen bzw. die Zugriffe auf die gespeicherten Daten werden i.d.R. via NSPersistentStores realisiert, nur dieser kann auf die internen Tabellen (Zuordnungen, Primarykey, Forgeinkey usw.) zugreifen - Stichwort Kapselung der Datenhaltung, -verwaltung. Dies soll eine Erleichterung sein, damit der Programmierer sich nicht damit auseinandersetzen muss. Ist Dir sicherlich bekannt. Eigentlich auch gut so, spart ja auch "etwas" Arbeit, aber damit wird das Ganze auch ein Stück weit aufwendiger wenn Daten exportiert und danach wieder importiert werden.

      Es gibt wohl eine Möglichkeit direkt auf das zugrundeliegende Datensystem zuzugreifen, aber wie mir richtigerweise mitgeteilt wurde, wenn Apple die innere Verwaltung/Handhabung der Daten ändert, endet dieser Weg in einer Sackgasse.
    • OSXDev schrieb:

      Im Grunde hast Du die Lösung schon selbst benannt - eigene Primary-, Forgeinkeys in den Tabellen einsetzen und die Beziehungen dahingehend aktualisieren. Ansonsten müsstest Du in der Importfunktion die Daten einer Plausibilitätsprüfung unterziehen, bevor diese dem DBS hinzugefügt werden. Je nachdem wie komplex die Relationen sind, ist dieser Weg sehr aufwendig und mitunter fehlerbehaftet.
      Danke, das bestätigt meine Wahrnehmung - und entspricht auch meiner Lösung in der alten App ... dort hatte ich einen solchen Key glücklicherweise implizit.

      Da ich die Kontrolle über das Datenmodell habe und noch in der Erstentwicklung bin, kann ich noch alles machen.

      Nutzt Ihr generische Fremdlösungen für Im-/Export aus Core Data oder schreibt Ihr die selber? Aufgrund von Besonderheiten (z. B. Images) und weil ich gerne alles verstehen möchte, tendiere ich zu letzterem...

      Mattes
      Diese Seite bleibt aus technischen Gründen unbedruckt.
    • MyMattes schrieb:

      ...

      Nutzt Ihr generische Fremdlösungen für Im-/Export aus Core Data oder schreibt Ihr die selber? Aufgrund von Besonderheiten (z. B. Images) und weil ich gerne alles verstehen möchte, tendiere ich zu letzterem...

      Mattes
      Also eine generelle Aussage kann ich da nicht treffen. Es kommt darauf an was gefordert ist und in welcher Zeit bzw. was das Budget hergibt.

      Persönlich verzichte ich lieber auf den Einsatz von Fremdlösungen - Stichworte: Lizenz, Haftung, Support usw.. Zudem ist es leichter die eigene Wissensbasis mit Eigenleistung zu erweitern. 8)
    • MyMattes schrieb:

      Die (Artikel-) Farbe ist eine "many-to-one"-Relation von der Entität Artikel auf die Entität Farbe ... diese Entität hat eigene Attribute, z. B. Titel, displayOrder etc.
      Die Entität Farbe hat eigene Attribute. Manche Attribute bzw. Attribute Zusammenstellungen dürfen nur einmal auftauchen. Keine Ahnung, dass könnte z.B. der Farbwert sein und ob die Farbe metallisch ist oder nicht. Da hast Du doch etwas, was die eine Farbe von der anderen Farbe unterscheidbar macht.
    • manoh schrieb:

      Manche Attribute bzw. Attribute Zusammenstellungen dürfen nur einmal auftauchen. Keine Ahnung, dass könnte z.B. der Farbwert sein und ob die Farbe metallisch ist oder nicht. Da hast Du doch etwas, was die eine Farbe von der anderen Farbe unterscheidbar macht.
      Da wird sich was finden! Die besagten Auswahllisten haben nur zwei Verwendungen: Eine zusätzliche Information für den Benutzer über die Charakteristika eines Artikels und Selektionskriterien für Artikellisten. Es gibt sie für Artikel-Eigenschaften wie Größe, Farbe, Material, Muster, Artikelkategorie und Warensortiment ... letztlich nur (erweiterbare) Listen von Strings. Wahrscheinlich werde ich einfach den jeweiligen Titel eines Listeneintrags unique erzwingen ... das macht aus Anwendersicht sogar Sinn :)

      Danke für's Mitdenken, Mattes
      Diese Seite bleibt aus technischen Gründen unbedruckt.
    • Vielleicht habe ich das Problem nicht richtig verstanden oder denke mal wieder zu einfach. Die einfachsten Lösungen sind aber meist die besten. ;)

      Wenn Du Objekte mit Referenzen untereinander nach JSON, XML oder in eine andere Form konvertieren möchtest, dann kannst Du dabei für jedes zu konvertierende Objekt eine eindeutige ID erstellen, welche Du dann für die Referenzierung unter den Objekten in der JSON, XML usw. Form verwendest. Da jedes Objekt ja nur einmal konvertiert wird, gibt es somit eine eindeutige ID für jedes Objekt. Diese IDs kannst Du dann einfach für jeden Objekttyp, also jede Klasse, fortlaufend nummerieren. Alternativ kannst Du auch fortlaufende IDs für alle Objekte verwenden. Dann hast Du einen universelleren Ansatz, den Du einfacher für alle möglichen Objektbäume wiederverwenden könntest. Mit einem Dictionary kannst Du Dir dann sehr einfach die bereits erzeugten IDs für die Objekte merken. Wenn Objekte mehrfach referenziert werden, dann verwendest Du die jeweilige ID für die Referenzierung in der JSON, XML usw. Form. Dies ist nichts anderes als z.B. der NS(Keyed)Archiver auch macht.

      Passend zu Deinem Objektbaum könntest Du also zuerst alle verwendeten Farbe Objekte konvertieren und dafür eindeutige IDs erstellen. Danach konvertierst Du alle verwendeten Produkt Objekte und referenzierst darin über die IDs auf die Farbe Objekte. Danach alle Liste Objekte und zuletzt die Shop Objekte.

      Ob es im Datenmodel bereits eindeutige IDs für die jeweiligen Objekte gibt ist dabei völlig unerheblich, da Du ja eigene IDs für die Referenzierung untereinander verwendest.
    • MCDan schrieb:

      Vielleicht habe ich das Problem nicht richtig verstanden oder denke mal wieder zu einfach. Die einfachsten Lösungen sind aber meist die besten. ;)
      Du denkst m. E. nicht zu einfach, Dein Ansatz ist auch nach meinem Verständnis der komplett saubere und generell verwendbare - daher bei mir oben auch die Idee, z. B. auf Basis der objectID (oder sonstwie) einen eigenen Identifier zu erstellen, den ich dann im Export / Import nutze.

      Das einzige, was ich dabei "unangenehm" finde, ist die Notwendigkeit beim Import z. B. des Produktes dann beim Referenzieren "meine" IDs auflösen zu müssen. Dazu sollte ich diese entweder als Attribut mit im NSManagedObject aufgenommen haben und kann Predicates nehmen, oder ich müsste parallel (z. B. aus dem JSON) ermitteln, welches bereits importierte Farben-Objekt welcher eigenen ID entsprach. Daher aus Bequemlichkeit der nicht so elegante Ansatz mit der Eindeutigkeit innerhalb von Core Data...

      Meine Todo-Liste ist noch lang und es wird noch etwas dauern, bis ich an die Realisierung des Ex-/Imports komme. Bis dahin werde ich mich zwischen pragmatisch (Uniqueness in Core Data) und optimal (Export-IDs) entschieden haben :)

      Danke! Mattes
      Diese Seite bleibt aus technischen Gründen unbedruckt.
    • MyMattes schrieb:

      Du denkst m. E. nicht zu einfach, Dein Ansatz ist auch nach meinem Verständnis der komplett saubere und generell verwendbare - daher bei mir oben auch die Idee, z. B. auf Basis der objectID (oder sonstwie) einen eigenen Identifier zu erstellen, den ich dann im Export / Import nutze.
      Der zu erstellende Identifier kann einfach eine fortlaufende Nummerierung sein und muss keinen direkten Zusammenhang zur objectID haben. Zum Mappen der objectID auf den Identifier kannst Du einfach ein Dictionary mit der objectID als Key verwenden. Ich habe dies jetzt nicht explizit getestet. Da objectID, also NSManagedObjectID, jedoch das NSCopying Protocol implementiert, sollte es als Key in einem Dictionary funktionieren.

      Somit kannst Du sehr einfach zu jedem Objekt bzw. jeder objectID den erstellten Identifier ermitteln. Eine Große Logik, wie der Identifier evtl. aufgebaut ist und wie man ggf. von einer objectID auf den passenden Identifier kommt entfällt somit.

      MyMattes schrieb:

      Das einzige, was ich dabei "unangenehm" finde, ist die Notwendigkeit beim Import z. B. des Produktes dann beim Referenzieren "meine" IDs auflösen zu müssen. Dazu sollte ich diese entweder als Attribut mit im NSManagedObject aufgenommen haben und kann Predicates nehmen, oder ich müsste parallel (z. B. aus dem JSON) ermitteln, welches bereits importierte Farben-Objekt welcher eigenen ID entsprach. Daher aus Bequemlichkeit der nicht so elegante Ansatz mit der Eindeutigkeit innerhalb von Core Data...
      Beim Import kannst Du auch wieder ein Dictionary mit den IDs als Key und den dazu erzeugten Objekten verwenden. Wenn Du dann ein Produkt importierst, welches z.B. auf eine Farbe mit der ID 4711 referenziert, dann verwendest Du einfach das passende Objekt zur ID als Key aus dem Dictionary, fertig. Die IDs, aus z.B. dem JSON, musst Du also nicht extra als Attribut im NSManagedObject aufnehmen.
    • Mir scheint das ein allgemeines Problem zu sein, und dieses hat nichts mit der verwendeten Technik zu tun.

      Nr. 1: Jedes Objekt braucht einen Owner in dem dieses gepflegt werden kann.

      Nehmen wir mal die Farbe. Diese kann nur vom Hersteller dieser definiert werden. Alle anderen haben diese dann zu verwenden. Sonst gibt es Bestellungen, mit undefinierten Farben. Damit diese verwendet werden können, benötigen diese auch einen eindeutigen Schlüssel. Dieser ist wie bei jeden anderen Objekt mitzuliefern.

      Ein anderes Objekt, welches auf einem Gerät erstellt wird, bekommt ja auch einen eindeutigen Schlüssel. Wenn dieser ausgespielt wird, identifiziert er auch später noch dasselbe Objekt. Existiert es im Zielsystem, muss es eben upgedatet werden, ansonsten ist es anzulegen. Nach dem einspielen, kann dieses dann im neuen System verwendet werden.

      Wird dies Objekt 2x angelegt mit unterschiedlichen Schlüsseln, kann an anhand der Attribute prüfen, ob es sich ggf. um eine Dublette handelt, dann frägt man halt dem Anwender, welches Objekt er behalten möchte. Wenn er das verkehrte Objekt verwirft, it er selbst schuld ;) sonst Du resp. deine Software

      Kurz und knapp, jedes Objekt das erstellt wird, benötigt einen Weltweit eindeutigen Schlüssel (bspw. UUID), über welches dieses identifiziert und getrackt wird.

      Die Technik wie das dann verteilt wird (XML, ZIP, Cloud Database, etc.) ist dann Geschmackssache.

      Schöne Grüsse
      Wolf
    • Es wird wohl auf das von @MCDan beschriebene Szenario hinauslaufen: Ein einfacher Algorithmus, der zum Export-Zeitpunkt für jedes Objekt eine ID vergibt und diese mit im JSON speichert. Ob als fortlaufende Nummer, Hash der objectID oder sonstwie, ist irrelevant.

      Beim Import führe ich dann ein (temporäres) Verzeichnis, welches (neue) Objekt für welche Id angelegt wurde, so dass ich dieses zum Wiederherstellen der Referenzen nutzen kann. Ein NSDictionary bietet sich geradezu an.

      Weltweit eindeutige IDs brauche ich hierbei nicht, sie werden nur im Rahmen des Ex-/Imports benötigt und nur durch meine App ... auch wenn dies ein grundsätzliches Problem darstellen dürfte: Ich brauche zum Glück keine global eindeutigen IDs für ein spezielles Rot ... das Problem dürfen andere lösen.

      Danke, so komme ich wahrscheinlich klar. Die Diskussion mit Euch hat mir viel bei der Klärung geholfen!

      Mattes
      Diese Seite bleibt aus technischen Gründen unbedruckt.
    • Für mich klingt das so, als ob man das generisch hinbekommt. Also Im-/Export (inkl. Merge) von CoreData nach JSON oder YAML. Da es CoreData schon länger gibt, hatte vllt. schon jemand anderes das Problem...

      Nur mal kurz gesucht. Da gibt es z.B. 3lvis/Sync. Ist allerdings (bzw. anscheinend) für Swift gedacht. Was aber daran interessant ist, wenn ich das jetzt richtig überflogen habe, dann wird hier User Info eines Attributes dafür verwendet, um ein Attribute vom Export auszuschließen bzw. als Primary Key zu deklarieren.
    • Interessantes Projekt, das auch einen eigenen Key im JSON hält ... ich sehe auch keinen anderen Weg.
      Sync requires your entities to have a primary key, this is important for diffing, otherwise Sync doesn’t know how to differentiate between entries.
      Für meinen Einsatz ist es over-kill, da ich kein Synching sondern nur Export / Import benötige. Insgesamt halte ich den Anteil an Fremdcode in meinen Projekten gerne minimal: Als Hobbyist kann ich mir das zeitlich leisten, lerne lieber die Problemlösung als fremden Code und erspare mir technische oder lizenzseitige Abhängigkeiten.

      Aber Du hast recht, das Problem sollte sich generisch lösen lassen und ich bin - einmal wieder - erstaunt, warum Apple dafür kein Standard-Framework o. ä. bietet. Kann ja noch kommen ... WKWebView lernt ja auch erst jetzt einen PDF-Export. Aber das ist ein anderes Kapitel :)

      Mattes
      Diese Seite bleibt aus technischen Gründen unbedruckt.

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von MyMattes ()

    • MCDan schrieb:

      Der zu erstellende Identifier kann einfach eine fortlaufende Nummerierung sein und muss keinen direkten Zusammenhang zur objectID haben. Zum Mappen der objectID auf den Identifier kannst Du einfach ein Dictionary mit der objectID als Key verwenden. Ich habe dies jetzt nicht explizit getestet. Da objectID, also NSManagedObjectID, jedoch das NSCopying Protocol implementiert, sollte es als Key in einem Dictionary funktionieren.
      Somit kannst Du sehr einfach zu jedem Objekt bzw. jeder objectID den erstellten Identifier ermitteln. Eine Große Logik, wie der Identifier evtl. aufgebaut ist und wie man ggf. von einer objectID auf den passenden Identifier kommt entfällt somit.


      [...]

      Beim Import kannst Du auch wieder ein Dictionary mit den IDs als Key und den dazu erzeugten Objekten verwenden. Wenn Du dann ein Produkt importierst, welches z.B. auf eine Farbe mit der ID 4711 referenziert, dann verwendest Du einfach das passende Objekt zur ID als Key aus dem Dictionary, fertig. Die IDs, aus z.B. dem JSON, musst Du also nicht extra als Attribut im NSManagedObject aufnehmen.
      Als abschliessender Kommentar zu diesem Thread: Ich habe es nun wie eingangs skizziert und mit dem Hinweis von @MCDan ergänzt gelöst:
      • Beim Export wird auf Basis der Object-IDs eine eindeutiger Identifier erzeugt. Ich nutze hier kein Dictionary, sondern hashe einfach nur, wobei ein MD5 ausreicht (keine sicherheitsrelevante Anwendung und zufällige Kollisionen wird es kaum geben).
      • Diese ID wird mit dem "Stammobjekt" im JSON gespeichert und beim Export von Referenzen als ausschließlicher Verweis genutzt.
      • Beim Import löse ich diese IDs wieder auf. Dabei prüfe ich in einem übergreifenden Dictionary, ob ein Objekt der jeweiligen ID schon erzeugt wurde. Wenn ja, nutze ich dieses, andernfalls wird das Objekt erzeugt und im Dictionary vermerkt.
      Der Import-/Export-Code liegt in den Core-Data-Klassen der jeweiligen Entität, hier ein Beispiel für die Sortimente eines Artikels:


      C-Quellcode

      1. - (NSDictionary *)attributes
      2. {
      3. // Export all attributes and related entities; store an additional unique key to resolve relationships
      4. NSMutableDictionary *exportDict = [NSMutableDictionary new];
      5. [exportDict setObject:[self.objectID.URIRepresentation.absoluteString md5] forKey:kSTSExportHashKey];
      6. if (self.displayOrder) [exportDict setObject:[NSNumber numberWithInt:self.displayOrder] forKey:kSTSExportDisplayOrderKey];
      7. if (self.isDefaultItem) [exportDict setObject:[NSNumber numberWithBool:self.isDefaultItem] forKey:kSTSExportDefaultItemKey];
      8. if (self.title) [exportDict setObject:self.title forKey:kSTSExportTitleKey];
      9. return exportDict;
      10. }
      11. + (instancetype)initWithAttributes:(NSDictionary *)attributes lookupDict:(NSMutableDictionary *)lookupDict
      12. {
      13. // Read hash from import and check if an object with this hash was already created (e.g. a picklist item); if success just return the object, otherwise create one, set its attributes and return it
      14. Assortment *importedItem;
      15. NSManagedObjectContext *managedObjectContext = [STSStorageProvider defaultStorageProvider].managedObjectContext;
      16. NSString *jsonHash = attributes[kSTSExportHashKey];
      17. if (!jsonHash) return nil;
      18. NSManagedObjectID *existingObjectID = lookupDict[jsonHash];
      19. if (existingObjectID)
      20. {
      21. importedItem = [managedObjectContext existingObjectWithID:existingObjectID error:nil];
      22. }
      23. else
      24. {
      25. importedItem = [NSEntityDescription insertNewObjectForEntityForName:kSTSEntityAssortment inManagedObjectContext:managedObjectContext];
      26. if (attributes[kSTSExportDisplayOrderKey]) importedItem.displayOrder = ((NSNumber *)[attributes objectForKey:kSTSExportDisplayOrderKey]).intValue;
      27. if (attributes[kSTSExportDefaultItemKey]) importedItem.isDefaultItem = ((NSNumber *)[attributes objectForKey:kSTSExportDefaultItemKey]).boolValue;
      28. if (attributes[kSTSExportTitleKey]) importedItem.title = attributes[kSTSExportTitleKey];
      29. lookupDict[jsonHash] = importedItem.objectID;
      30. }
      31. return importedItem;
      32. }
      Alles anzeigen
      Mir gefällt es, macht auf mich einen sauberen Eindruck und hat keine Abhängigkeiten wie z. B. einen unique key zum Datenmodell. Exzessive Tests stehen noch aus :)

      Mattes
      Diese Seite bleibt aus technischen Gründen unbedruckt.