CoreData Record speichern und lesen

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

    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.

    • CoreData Record speichern und lesen

      Hallo Zusammen,

      ich habe derzeit ein merkwürdiges Problem, vielleicht hat ja der eine oder andere einen passenden Tipp.

      In der einen Klasse erstelle ich einen Record, versorge ihn mit entsprechenden Werten und speichere diesen.

      Später geht es dann zum auswerten. Dazu habe ich eine separate Klasse und in dieser kann ich dann auch den Datensatz wieder einlesen.

      Das würde ja soweit passen.

      Das Merkwürde daran ist, dass ich nur die halben Daten des Records bekommen, als die die ich zuvor gespeichert habe. Habe die Versorgung schon X-fach überprüft und die ist konsistent.

      Hat hier jemand eine Idee, weshalb beim lesen des Records nur die halben Werte/Felder mit Werten versorgt werden? ;(

      Schön mal vielen Dank
      Wolf
    • Ich vermute, mit "Datensatz" meinst Du eine Core-Data-Objekt mit Eigenschaften (analog zur definierten Entität mit Attributen)? Und von diesen Eigenschaften werden nur einige gespeichert?

      Ohne etwas mehr Infos ist alles Kaffeesatzlesen: Wie erzeugst Du das Core-Data-Objekt, wie greifst Du wieder darauf zu und was passiert in der Zwischenzeit? Wurde die App beendet und wann speicherst Du den Kontext? Etwas Code wäre sicher hilfreich... Ist vielleicht ein Attribut aus Versehen als "transient" definiert? Es gibt so viele Möglichkeiten, Mist zu bauen, dass Du zum Helfen etwas mehr Hintergrund liefern musst.

      Mattes
      Diese Seite bleibt aus technischen Gründen unbedruckt.
    • Hallo Mattes,

      hier mal die Speicherroutine:

      Quellcode

      1. updateTables()
      2. updateDisabledMembers()
      3. guard cds.hasChanges else { return }
      4. cds.performAndWait {
      5. do {
      6. try cds.save()
      7. print(dbRecord?.Left) //UUID?
      8. print(dbRecord?.Right) //UUID?
      9. print(dbRecord?.Date) //Date?
      10. print(dbRecord?.id) //UUID?
      11. } catch {
      12. isError = true
      13. }
      14. }
      Alles anzeigen


      Die Printangaben dienen dazu zu validieren ob die Attribute auch gesetzt sind. und diese sind auch noch nach dem speichern wunderbar vorhanden

      Dazwischen wird nicht viel gemacht, es wird der TabBarController gewechselt (also anderer Reiter). In diesem sollen die Zahlen dargestellt werden.

      Es ist kein Attribut in als "trassiert" definiert. wurde soeben nochmals überprüft.

      Die App wird zwischenzeitlich nicht verlassen, sondern nur der Tab gewechselt.

      Die Klasse zum speichern hat nur die Funktion die Daten in die Entitätsstruktur zu bringen zu validieren und zu speichern. Also relativ trivial...

      Schöne Grüsse
      Wolf

      //AddOn:
      Gespeichert wird in ein SQLite CoreData Objekt. Der CoreDataStack ist als Singleton definiert und steht in der gesamten Anwendung zentral zur Verfügung.

      Auf das Objekt wird zwischen den speichern und dem lesen nicht zugegriffen. Die Übergabestruktur von den anderen Klassen ist gekapselt und als "Struct" definiert. Referenzen werden daher keine ausgetauscht

      Hier etwas mehr Code der Speicherroutine und der aufrufenden Routine

      Quellcode

      1. public func saveMe() throws {
      2. validate(); guard err == nil else { throw err! }
      3. updateData()
      4. bildVerkleinern()
      5. updateMembers()
      6. do {
      7. try privateSave()
      8. reset() //rücksetzen der Daten
      9. }
      10. catch {
      11. throw dspErrors.dbSpeicherFehler
      12. }
      13. }
      14. private func privateSave() throws {
      15. var isError: Bool = false
      16. func updateTables() {
      17. ...
      18. }
      19. func updateDisabledMembers() {
      20. ...
      21. }
      22. updateTables()
      23. updateDisabledMembers()
      24. guard cds.hasChanges else { return }
      25. cds.performAndWait {
      26. do {
      27. try cds.save()
      28. } catch {
      29. isError = true
      30. }
      31. }
      32. if isError {
      33. throw errors.dbSpeicherFehler
      34. }
      35. }
      Alles anzeigen

      Die Leseroutine sieht so aus:

      Quellcode

      1. private func getRecords() {
      2. let eingeleseneBelegeFromDB = TMyData.findRecords(Id: Id!, ctx: cds)
      3. for localEingelesenerBeleg in eingeleseneBelegeFromDB {
      4. let x = MyStruct()
      5. x.id = localEingelesenerBeleg.id
      6. ... //Hier fehlen dann verschiedene Attribute
      7. myReceipts.append(x)
      8. }
      9. }
      also unspektakulär...
      nur fehlen dann bei manchen Attributen die erwarteten Daten

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von Wolf ()

    • Liegt's an mir? Ich hatte eigentlich ein paar Codezeilen erwartet, in denen Du z. B. mit NSEntityDescription insertNewObjectForEntityForName: neue Objekte anlegt, deren Properties setzt und z. B. über einen Fetch wieder liest.

      Stattdessen sehe ich in Deinem Code viele eigene Methoden-Aufrufe, die mir beim Verständnis so rein gar nicht weiterhelfen. Zudem verwirrt mich Swift-Syntax noch immer ... Hast Du einmal geprüft, ob Du im Rückgabe-Array von TMyData.findRecords überhaupt das vorher angelegte Objekt enthalten ist (einfach mal die objectIDs ausgeben). Vielleicht schaust Du auf ein ganz anderes Objekt...

      Mattes
      Diese Seite bleibt aus technischen Gründen unbedruckt.
    • Hi Mattes,

      bei der Rückgabe aus TMyData.findRecords, werden die gefundenen Records als Array zurückgeliefert. Das ist ein normaler fetchRequest. Da ich aktuell teste mache ich da immer sauber und kontrolliere die auch die Testdaten. Das ergebnis ist, dass genau die Daten geliefert werden die ich erwarte. Diese daten werden dann in in der For Schleife travesiert... auch das funktioniert wunderbar. nur fehlen halt bestimmte Werte welche ich vorher versorgte.

      insertNewObjectForEntityForName, so wird hier kein Datenbankobjekt mehr angelegt. Das geht aktuell über TEnity(context: <managedContext>) dann speichern und gut ist es, bis auf diese Ausnahme.
      Das mit den ObjectId’s werde ich mal tun. Wusste bislang nicht, dass es sowas gibt...
      ... soetwas ähnliches war auch schon mal meine Vermutung, dass eine spätere Version die erste gespeicherte überschreibt... werde das mal prüfen

      cds, ist einfach der CoreDataStack, welcher den ManagedObjectContext enthält. Das Ganze Progy ist halt zwischenzeitlich etwas größer geworden... und wird über eine SwiftUI gesteuert.


      Normal funktioniert das ja, wenn man die üblichen Probleme mit SwiftUI nicht mit einbezieht...
      ... dachte die hätte ich zwischenzeitlich im griff, da ich die DB Objekte möglichst schnell wieder destroye um keine CoreData Referenzen im Memory zu halten...

      Der Standard Fetch läuft... habe allerdings dieses mal viele Optionals eingebaut... bekomm sie aber nicht raus, da ich grad keine Defaults für die UUID einstellen kann ?(

      Schöne Grüsse
      Wolf