Binding UserDefaults->ArrayController

  • Binding UserDefaults->ArrayController

    Hallo

    ich habe in meinen UserDefaults ein Array mit Strings gesichert. Das möchte ich jetzt in einer Tabelle anzeigen lassen und da auch ändern können. Wie mach ich das?
    Einen NSArrayController erstellen und dessen Content-binding auf den SharedUserDefaultsController.meineStringsArray setzen?
    danke

    David
  • David, hast Du schonmal nachgesehen woher die Warnung:

    "<NSTableColumn: 0x31e070>): [<NSCFString 0x3bf670> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key ."

    kommt? Das klingt fishy

    Alex
    The only thing that really worried me was the ether.
  • Original von below
    David, hast Du schonmal nachgesehen woher die Warnung:

    "<NSTableColumn: 0x31e070>): [<NSCFString 0x3bf670> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key ."

    kommt? Das klingt fishy

    Alex


    kommt hier nicht ?(

    Original von Tom9811
    Ist der Transformer bidirektional?


    falls du damit allowsReverseTransformation meinst, das ist an
  • OK, Dein Sample funktioniert bei mir fast gar nicht, auf 10.3.7 kann ich gar keine neuen Sachen eintragen. Auf XX.X gibt es die Warnung, und das nicht ohne Sinn. Das Array, welches Dein Transformer zurückgibt ist:

    <CFArray 0x351ea0 [0xa0080148]>{type = mutable-small, count = 5, values = (
    0 : <CFString 0x351f20 [0xa0080148]>{contents = "bla"}
    1 : <CFString 0x351f60 [0xa0080148]>{contents = "two"}
    2 : <CFString 0x351fa0 [0xa0080148]>{contents = "drei"}
    3 : <CFString 0x351fe0 [0xa0080148]>{contents = "blablabalabla"}
    4 : <CFString 0x351ee0 [0xa0080148]>{contents = ""}
    )}

    Ob "Object Class" NSString so funktioniert, weiss ich nicht.

    Wenn mich mein löcheriges Hirn nicht täuscht erwartet das übliche Binding einen Array of Dictionaries. Das erklärt auch, warum die Warnung kommt, CFString sei nicht kv-compliant.


    Gruss

    Alex
    The only thing that really worried me was the ether.
  • So kann man das nicht sagen. Das im Array Controller selektierte Objekt muss ja einen Key auf irgendwas haben. Das funktiniert ja über KVO und KVC. Welchen Key haben den Strings? Welchen hast du überhaupt eingegeben?

    Du kannst das auf dreierlei wegen herstellen.

    Entweder du schreibst einfach ein Dictionary. Ein Dictionary hat seine Keys immer als Keys über Accessoren erreichbar. Wenn du also den String in ein Dictionary mit dem Key value stopfst, kommst du über den Schlüssel value an deinen String, weil das Dictionary setValue: und value als Accessoren anbietet.

    Oder aber du schreibst dir eine Klasse Irgendwas, die für einen Key einen String liefert und umgekehrt einen setzen kann.

    Oder du leitest String ab und machst selbst ein Accessorpaar.

    Aber so bietet String ja keinen Key an, weshalb man auch nicht ordentlich darauf zugreifen kann.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Mir geht es weniger um die Funktionalität, als daran, dass die Binding Creation doch nachschauen könnte, ob der verwendete Transformer bidirektional ist und verneindenfalls das "Zurückspeichern" verweigert.

    Also, wenn ich einen einfachen EuroDollar VT nehme, dann muss er doch meine Eingabe auch wieder zurückrechnen. Nicht damit der Datentyp stimmt, nicht, damit der Wert stimmt, sondern weil er ja nicht einfach das transformierte Objekt an die Stelle des ursprünglichen schreiben kann. Er muss doch irgendwie die Transformation rückgängig machen.

    Aber ich habe es noch nie probiert. War also nur eine Ahnung.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Also ich hab das gnaze jetzt mal analysiert und bin zu folgendem Schluss gekommen: mit den Hausmitteln der Bindings geht es nicht. Das liegt daran, dass der ArrayController beim ändern eines Wertes versucht, für das entsprechende Item etwas auf einen leeren KeyPath zu speichern, was natürlich reichlich sinnbefreit ist. Jetzt gibt es zwei Möglichkeiten, dem ganzen da auf die Sprünge zu helfen:

    1) Man schreibt sich eine subclass von NSMutableString, die das setzen von Values auf einen leeren KeyPath als setzen der eigenen Value ansieht und sich somit selber verändert. Man müsste dann im IB als Datenklasse eben diese Subklasse angeben.
    2) Man überschreibt eine private Methode von NSArrayController und verändert somit das Schreibverhalten. Man müsste dann im IB einfach die Klasse des ArrayControllers ändern.

    Ich habe mich aus der Einfachheit Gründen für das zweite entschieden. Die betreffende Methode ist

    Quellcode

    1. - (void)_setMultipleValue:(id)value forKeyPath:(id)path atIndex:(unsigned int)index;
    . Den Rest kann man damm im angehängen Beispiel nachvollziehen :)

    HTH

    Max