OS X Swift Core Data fetchRequest

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

Macoun 2019 - Frühbucherrabatt bis 26.7.2019

  • OS X Swift Core Data fetchRequest

    Hallo,

    ich nutze zum erste Mal Core Data und benötige mal einen Denkanstoß.

    NSFetchRequest liefert mir doch eine Ergebnismenge der abgefragten Entität zurück - vergleichbar mir der SELECT-Anweisung.

    Anbei mal der Quellcode mit dem ich alle Personendaten ausgebe. Das funktioniert auch tadellos.

    Quellcode

    1. people = try managedContext.fetch(fetchRequest)
    2. for person in people
    3. {
    4. print("Neue Entität: ")
    5. print(person.value(forKey: "vornamen")!)
    6. print(person.value(forKey: "nachnamen")!)
    7. print(person.value(forKey: "strassennamen")!)
    8. }


    Wie greife ich nun auf einen bestimmten Datensatz z.B. den 3.'ten und auf dessen Attribut z.B. "alter" zu?


    Quellcode

    1. let iPersonAlter = person.value(forKey: "alter")
    2. if (iPersonAlter == 0) // An dieser Stelle erhalte ich einen Fehler!
    3. { ... }
    Obiger Quellcode (s. Zeile 1) liefert lt. Debugger ebenfalls eine Ergebnismenge zurück. iPersonAlter beinhaltet also mehr als einen Wert. Außerdem erhalte ich folgende Fehlermeldung: "Binary operator '==' cannot be Applied to operads of type 'Any' ant 'Int', welche ja bestätigt, dass iPersonAlter eine Menge enthält und nicht einen einzelnen Wert eines Datensatzes.


    Kann mir irgendjemand eine plausible Erklärung mitteilen. Außerdem wäre es prima wenn mir jemand erklären könnte wie ich auf einen bestimmen Datensatz der Menge und auf dessen Attribute gezielt zugreifen kann?

    Danke.
  • Mac & i Test Abo
  • matz schrieb:

    Wie du hier siehst developer.apple.com/documentat…nagedobject/1506613-value liefert value(forKey:) ein Any? zurück.

    Mal ins Blinde geschossen:

    Quellcode

    1. guard let iPersonAlter = person.value(forKey: "alter") as? Int else { fatalError("Could not find value for key") }

    @matz: Du hast ins Schwarze getroffen. :D Es funktioniert einwandfrei.


    Quellcode

    1. guard let iPersonAlter = person.value(at: 3, inPropertyWithKey: "alter") as? Int else { fatalError("Could not find value for key") }
    Ich habe jedoch angenommen, dass es sich bei der Ergenissmenge von fetchRequest um eine Art von Dictionary handelt. Auf dieses unter Angabe der Indexvariable und Key zugegriffen werden kann, um gezielt einen Wert auszulesen.

    Obiger Befehl würde genau das benötigte Ergebnis liefern. Jedoch erhalte ich folgende Fehlermeldung: "valueAtIndex:inPropertyWithKey: Index != 0 for non-toMany key". ?( Ich habe nur eine Entität definiert. In dieser habe ich verschiedene Attribute angelegt. Es existiert keine Beziehung (Releationship) zu anderen Entitäten. Wo liegt hier der Fehler?



    P.S.:Gibt es einen Viewer mit dem ich den Inhalt der verwendeten *.xcdatamedeld Datei einsehen kann? Wie kann sonst der Inhalt eingesehen werden, meine ohne via Code zu schreiben?

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von OSXDev () aus folgendem Grund: Ergänzung

  • OSXDev schrieb:

    Also ohne in einer Schleife die Rückgabemenge zu durchlaufen um gezielt z.B.: auf den 3.'ten Eintrag der Ergebnismenge zuzugreifen?
    Natürlich, du kannst dir doch aus einem Array das entsprechende Objekt mit einem Index abholen.


    OSXDev schrieb:

    Auf dieses unter Angabe der Indexvariable und Key zugegriffen werden kann um gezielt einen Wert auszulesen. Jedoch scheint dies wohl nicht der Fall zu sein, oder?
    Kannst du doch tun. Du kannst auch einfach für jede Entity eine Klasse nutzen und mit den Properties arbeiten.

    OSXDev schrieb:

    Wie kann sonst der Inhalt eingesehen werden, meine ohne via Code zu schreiben?
    CoreData hat SQlite drunter, guck das du an die entsprechende Datei kommst, dann kannst es dir mit jedem SQlite-Viewer anschauen.
  • matz schrieb:

    OSXDev schrieb:

    Also ohne in einer Schleife die Rückgabemenge zu durchlaufen um gezielt z.B.: auf den 3.'ten Eintrag der Ergebnismenge zuzugreifen?
    Natürlich, du kannst dir doch aus einem Array das entsprechende Objekt mit einem Index abholen.

    OSXDev schrieb:

    Auf dieses unter Angabe der Indexvariable und Key zugegriffen werden kann um gezielt einen Wert auszulesen. Jedoch scheint dies wohl nicht der Fall zu sein, oder?
    Kannst du doch tun. Du kannst auch einfach für jede Entity eine Klasse nutzen und mit den Properties arbeiten.

    OSXDev schrieb:

    Wie kann sonst der Inhalt eingesehen werden, meine ohne via Code zu schreiben?
    CoreData hat SQlite drunter, guck das du an die entsprechende Datei kommst, dann kannst es dir mit jedem SQlite-Viewer anschauen.
    zu Deinen Antworten 1.:

    Quellcode

    1. guard let iPersonAlter = person.value(at: 3, inPropertyWithKey: "alter") as? Int else { fatalError("Could not find value for key") }
    Funktioniert leider nicht s. Fehlermeldung im obigen Beitrag.

    zu 2.:
    Dies scheint mir ein prima Ansatz zu sein. Zu diesem habe ich jedoch noch ein paar Fragen:
    - Da ich in diesem Fall nicht mehr mit dem managedContext arbeite, muss ich jede Änderung eines Datensatzes mit diesem Abgleichen bevor ich diesen zurück speichere.
    - Ich könnte alle Datensätze löschen und die Klasse vollständig zurückschreiben lassen. Doch erscheint mir dies keine ideale Lösung zu sein.

    Gibt es vielleicht eine andere Lösungsansätze auf diesen Fall bezogen?

    zu 3.:
    Kannst Du mir einen SQlite-Viewer empfehlen?
  • OSXDev schrieb:

    Funktioniert leider nicht s. Fehlermeldung im obigen Beitrag.
    Moment: Deine Person ist ein einzelnes Objekt und kein Array!

    Das kannst du mittels

    Quellcode

    1. guard let iPersonAlter = persons[2].value(forKey: "alter") as? Int else { fatalError() }
    erreichen.


    OSXDev schrieb:

    Kannst Du mir einen SQlite-Viewer empfehlen?
    Ja, den integrierten von macOS (einfach im Terminal sqlite3 nutzen) oder diesen hier sqlitebrowser.org/

    Hatte auch immer den von Firefox genutzt, ist aber nicht mit Quantum kompatibel.
  • matz schrieb:

    OSXDev schrieb:

    Funktioniert leider nicht s. Fehlermeldung im obigen Beitrag.
    Moment: Deine Person ist ein einzelnes Objekt und kein Array!
    Das kannst du mittels

    Quellcode

    1. guard let iPersonAlter = persons[2].value(forKey: "alter") as? Int else { fatalError() }
    erreichen.


    OSXDev schrieb:

    Kannst Du mir einen SQlite-Viewer empfehlen?
    Ja, den integrierten von macOS (einfach im Terminal sqlite3 nutzen) oder diesen hier sqlitebrowser.org/
    Hatte auch immer den von Firefox genutzt, ist aber nicht mit Quantum kompatibel.

    @matz: Hmmm - mal wieder den Wald vor lauter Bäumen nicht gesehen. :D Vielen Dank. :thumbsup: