Core Data/Cocoa Bindings - Duplikate vermeiden

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

  • Core Data/Cocoa Bindings - Duplikate vermeiden

    Hey Leute!

    Ich weiss, die Überschrift ist jetzt nicht besonders vielsagend...
    Konnte zu meinem Problem leider keinen passenden Eintrag hier im Forum finden, also beschreib ich Euch mal mein Anliegen:

    Ich arbeite gerade an einer iPhone App welche eine Art Fragenkatalog beinhaltet - ein Nachschlagewerk.
    Jede Frage ist mit Schlagwörtern versehen, welche in einem TableView angezeigt werden, tippt man auf eines, sieht man im nächsten TableView eine Liste dazu passender Fragen. Danach gehts weiter zum eigentlichen Inhalt, (derzeit) ein WebView, dass mir Text anzeigt, also die Frage und die dazugehörige Antwort und Erleuterung usw...
    So. Der iPhone Part funktioniert soweit.

    Das ganze ist allerdings nur zum Nachschlagen gedacht, weshalb die Daten da irgendwie rein müssen. Also hab ich begonnen mir eine Mac App zu bauen, mit der man die Einträge bearbeiten kann.

    Das ganze basiert eben auf Core Data, ich hab dazu folgende beiden Entities angelegt:

    "Keyword" mit dem Attribut
    "name" (NSString)
    und der Relation
    "questions" auf Question (NSSet)

    "Question" mit Attributen
    "number" (NSNumber)
    "question" (NSString)
    "text" (NSString)
    und Relation
    "keywords" auf Keyword (NSSet)

    Das ganze habe ich dann per ArrayController im IB an TableView, TextField, ComboBox gebunden.
    Ein TableView zeigt mir sämtliche Fragen im Katalog, wähle ich eine zeigen mir daneben ein TextField Fragennummer, eines die Frage, eine ComboBox die möglichen Keywords, ein TableView die zur Frage gehörenden Keywords und ein TextView den in HTML formatierten Text zur Frage an.

    In einer weiteren Ansicht eines TabViews gibt's das ganze dann umgekehrt: dort zeigt ein TableView alle gespeicherten Keywords an und daneben in TextField, ComboBox und TableView die diesem Keyword zugewiesenen Fragen.

    Die Idee dahinter ist: Ich lege zb eine Frage an und weise ihr dann die passenden Keywords zu oder gebe ein neues ein, falls es noch nicht vorhanden ist. Oder aber ich lege einfach ein Keyword an und weise dem dann die passenden Fragen zu. Dabei kann ein Keyword auf mehrere Fragen verweisen und eine Frage kann wiederum mit mehreren Keywords "getaggt" sein.

    Jetzt mein Problem: Wenn ich jetzt zwei Fragen eintrage und denen ein gleiches Keyword zuweise, scheint es in der Liste der Keywords doppelt auf. Ich hatte ja gehofft, dass Durch die Auswahl eines Keywords in der ComboBox automatisch eine Referenz auf das bereits existierende Keyword Objekt angelegt wird, dem ist aber offensichtlich nicht so. Umgekehrt ist es natürlich genauso.

    Kann ich im IB irgendwas einstellen, damit sich das Programm so verhält wie ich möchte, oder muss ich dieses Verhalten in Code schreiben? Oder hab ich da einen Denkfehler drin?

    Falls es sich jemand genauer anschauen mag, hier mein Xcode Projekt:

    Projekt download

    Vielen Dank schon mal für jeden Hinweis!

    Herzlichst,
    Chris.
  • Aus Zeitgründen habe ich mir das Projekt nicht angeguckt, aber ich schätze, du hast da einfach einen Denkfehler.

    Was du einträgst sind Zeichenketten. Was du erwartest sind Referenzen.
    Idealerweise eine Mischung: tipp eine Zeichenkette ein und wenn es die bereits gibt, leg ne Referenz darauf an - sonst erstelle sie und leg ne Referenz darauf an.

    Vermutlich betrachtest du Core Data falsch. Deine 'Keywords' Relationship ist ein NSSet mit x Keywords.
    Es gibt überhaupt keinen Zusammenhang der Keywords von 'Frage 1' und den Keywords von 'Frage 2', da sie an die Fragen gebunden sind.

    Einfacher und sinnvoller ist es, wenn du dir einen ganzen Schwung Keywords anlegst und diese dann deinen Fragen zuordnest.
    Denn im Allgemeinen sind 'Allgemeinwissen' von Frage 1, 'Allgemeinwissen' von Frage 2 und 'Allgemeinwissen' von Frage N drei komplett unterschiedliche Objekte, die nur zufällig einen gleichen String beinhalten.

    Statt also einfach direkt in deiner App via Bindings die Objekte neu anzulegen müsstest du die Eingaben prüfen, schauen ob ein Keyword mit diesem String bereits existiert und dann via Code entweder das Keyword erzeugen und zuweisen oder die Zuweisung zu dem existenten Keyword vornehmen.
    «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

    Iä-86! Iä-64! Awavauatsh fthagn!

    kmr schrieb:

    Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
  • Also erstmal Danke Lucas für Deine Antwort.

    Ja sowas in der Richtung hab ich mir schon gedacht. Mir ist Klar, dass die einzelnen Keywords eigentlich nichts miteinander zu tun haben und eigentlich nur ein Attribut gleich haben. Dann werd ich wohl im Code überprüfen müssen, ob es ein entsprechendes Keyword schon gibt mit dem gleichen String wie der eingegebene.

    Aber gibt es nicht irgendwie die Möglichkeit ein Attribut als "unique" zu definieren? Sodaß CoreData das für mich Überprüft?

    thx, Chris.
  • Also wenn Du die Keywords als eigene Entity hast und zwischen Frage und Keyword ein m:n-Beziehung besteht musst Du lediglich bei der Keyword-Erzeugung überprüfen, ob es schon eine entität mit gleichem Namen gibt. Da die relationship ein NSSet ist, sorgt CoreData dafür, dass es keine doppelten Eintrage gibt. Aber die Auswahl sollte dann keine Combobox sondern jeweils ein tableview sein (m:n). Beste Grüsse, Markus
  • Aber gibt es nicht irgendwie die Möglichkeit ein Attribut als "unique" zu definieren? Sodaß CoreData das für mich Überprüft?

    Am besten in der Validierungsmethode des Core Data Attributs. Diese musst Du implementieren.

    Quellcode

    1. validatevalue:forKey:
    oder so. Hab's nicht genau im Kopf.

    ... Und, was Du dann mit diesem 'Fehler' anstellst (Fehlerbehandlungsroutine).

    No.
  • Hey Leute, danke für Eure Ratschläge.
    @Markus: Ja, dass es in einem Set keine mehrfachen gleichen Objekte gibt ist mir klar, aber da mir ein NSArrayController offenbar automatisch ein neues NSManagedObject erzeugt und dem dann wieder das gleiche "name"-Attribut zuweist. Das heisst ich hab dann zwar ein "gleiches" Objekt mit dem selben Namen aber eben nicht das "selbe" und damit fügt es CoreData einfach ein ohne zu motzen. :)

    @No: mit validateValue: forKey: kann ich halt überprüfen ob mir der Attributwert so passt, aber das ist ja nicht was ich will, ich will eigentlich überprüfen ob es ein Objekt mit dem betreffenden Namen schon gibt und wenn, dann will ich ein Question Objekt mit ebendiesem verknüpfen und wenn es noch keines gibt ein neues anlegen.
    Da ist doch validateValue: der falsche ort dafür oder? denn da hab ich ja schon ein konkretes NSManagedObject. Also an welcher stelle sollte ich das besser schreiben?
    Ich hab das ganze jetzt mal in eine eigene Methode addKeyword: gepackt, welche das aktuell eingegebene Keyword aus der ComboBox übernimmt, überprüft obs da schon ein Objekt gibt und eben jenachdem ein neues Objekt einfügt und mit der aktuell ausgewählten Frage verknüpft oder ein vorhandenes benutzt. Jetzt hab ich dann aber ein Problem, wenn jemand ein Keyword in der Tabelle editiert, dann wird nämlich nichts überprüft. natürlich. Also ist jetzt meine Frage, wo ich das an zentraler Stelle am besten mache dieses "überprüfen und ggf. vorhandenes Objekt verknüpfen..."

    Sorry, ich hab echt grad keinen Schimmer... :(

    Chris.