Struct error

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.

  • Struct error

    Hallo zusammen,

    ein neuer Tag ein neues Problem und ich hoffe ihr könnt mir hier eine kleine Denkstütze geben.

    Folgende Situation

    ich habe eine MySQL Datenbank und eine PHP-API. Über die API bekomme ich Werte im JSON-Format an meine IOS-APP geliefert. Diese Werte möchte ich nun weiterverarbeiten.

    Ich habe ein Tableview und möchte die Daten dort in einzelnen Cells anzeigen lassen.

    Dafür wurde nun ein struct angelegt:

    Quellcode

    1. ​struct mydata {
    2. let id: String
    3. let name: String
    4. let description: String
    5. }
    6. var data = [mydata]()


    dann habe ich eine Methode, die die JSON Daten holt und eigentlich das struct füllen soll.

    Quellcode

    1. ​func initializeData() {
    2. func getJSONData(postparam: String) -> String{
    3. // hole Daten von der API
    4. // return String
    5. }
    6. func JSONParseArray(jsonString: String) -> [AnyObject] {
    7. // Parse den JSON-Datenstring
    8. // return Array
    9. }
    10. func work() -> [AnyObject]{
    11. // Hole die MySQL Daten
    12. let getData = getJSONData("action=getData")
    13. // Lege das Hauptarray an
    14. var DataArray:[AnyObject] = []
    15. // Parse den JSON-Datenstring
    16. for elem: AnyObject in JSONParseArray(getData) {
    17. let id = elem["id"] as String
    18. let name = elem["name"] as String
    19. let description = elem["description"] as String
    20. // pro MySQL Eintrag ein neuen Array
    21. var DataArrayIn:[String] = []
    22. // Neues Array füllen
    23. DataArrayIn.append(id)
    24. DataArrayIn.append(name)
    25. DataArrayIn.append(description)
    26. // Neues Array in Hauptarray fügen
    27. DataArray.append(DataArrayIn)
    28. }
    29. //Hauptarray (multidimensionales Array)
    30. return DataArray
    31. }
    32. }
    Alles anzeigen


    Nun habe ich die Daten in einem Array und möchte diese in struct schreiben.

    Quellcode

    1. ​// Beispiel Array
    2. [
    3. (1,name1,"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam"),
    4. (2,name2,"Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod")
    5. ]


    Das ganze mache ich ja mit

    Quellcode

    1. ​let dataX = mydata(id: "XYZ-ID", name: "XYZ-NAME", description: "XYZ-DESCRITION")
    2. self.data = [dataX]


    Also dachte ich mir alles klar ich bau eine For Schleife und gehe das Array durch. Bei jedem Durchlauf speichere ich dann die Daten in struct.

    Quellcode

    1. ​let workdata = work()
    2. var count = 0
    3. // Hauptarray durchlaufen
    4. for element in workdata {
    5. var newData = mydata(id: element[0].string, name: element[1].string, description: element[2].string)
    6. count++
    7. }
    8. // schreibe die Daten in
    9. self.mydata = [newData]
    Alles anzeigen


    Nun wird natürlich die newData Variable immer wieder überschrieben und ich bekomme einen Fehler "Use of unresolved identifier newData"

    Das Überschreiben der Variable kann ich durch den Counter korrigieren, aber dieser Fehler ist mir nicht ganz klar. Bei Google gibt es reichlich Lösungsansätze, allerdings beziehen die sich immer auf eine Klasse nicht auf eine Variable.

    Ich ging nun davon aus das die Variable "newData" die in der For-Schleife erstellt wird schlichtweg nicht gefunden wird. Das würde aber bedeuten das XCode die For-Schleife nicht erst durchläuft, bis es im Script weiter geht. Ehrlich gesagt kann ich mir das nicht vorstellen.

    Hat jemand eine Idee woran es liegen kann? Wo liegt mein Denkfehler bzw. bin ich total auf dem Holzweg und es geht viel einfacher?

    Danke euch :)
  • Sehr schön ich habe das Problem nun doch gelöst :)

    Die For-Schleife sieht nun so aus:

    Quellcode

    1. ​for element in wordata {
    2. var str1: String = element[0] as String!
    3. var str2: String = element[1] as String!
    4. var str3: String = element[3] as String!
    5. var str4: String = element[4] as String!
    6. self.recipes.append(Recipe(id: str1, name: str2, description: str3))
    7. }


    und das

    Quellcode

    1. ​self.mydata = [newData]


    entfällt komplett.

    Dennoch würde mich mal interessieren, ob die Spezis hier im Forum das ganze völlig anders gemacht hätten. Man lernt ja nie aus!

    Ist das so ok oder meint ihr das sollte grundsätzlich anders gelöst werden?

    Grüße
  • DKCode schrieb:

    Ich ging nun davon aus das die Variable "newData" die in der For-Schleife erstellt wird schlichtweg nicht gefunden wird. Das würde aber bedeuten das XCode die For-Schleife nicht erst durchläuft, bis es im Script weiter geht. Ehrlich gesagt kann ich mir das nicht vorstellen.


    Nein, es hat nichts mit Xcode zu tun. So wie du die For-Schleife programmiert hast, wird der Fehler in jeder Programmiersprache passieren. Ich sag nur lokale Variablen.
  • Noch ein klares "Nein" zu NSDictionary.
    Erstens ist das eh "Legacy" für Swift, vor allem imho aber schlechter Stil:
    Daten "von aussen" darf man nicht trauen, und in einem NSDictionary kann fast alles drin stecken (oder auch fehlen...).

    Mit Objective-C war das Anlegen einer neuen Klasse ja ziemlich hoher Aufwand, bei Swift fällt diese "Entschuldigung" für Dictionaries aber weitgehend weg (außerdem gibt's endlich Tupel, wenn der Aufwand immer noch zu groß empfunden wird).
  • [DKCode]
    Lass Dir nix einreden. Wenn Du lediglich eine Repräsentation Deines JSON Krams haben möchtest ohne weitere Methoden dran, dann langt ein Struct.
    Im Grunde ist Swift darauf ausgelegt, für die Darstellung von Datenstrukturen leichtgewichtigere Möglichkeiten als Objekte anzubieten.
    Deshalb wurden die Structs und Enums doch so aufgepumpt.

    Dein Fehler liegt in den Grundlagen.

    Quellcode

    1. var count = 0
    2. for element in workdata {
    3. var newData = mydata(id: element[0].string, name: element[1].string, description: element[2].string) count++
    4. }
    5. self.mydata = [newData]

    So sieht das nach Blödsinn aus.
    Du musst schon jedes einzelne Element irgendwo speichern.
    Sinngemäß (syntaktisch mitunter fehlerhaft, ich mache halt noch kein Swift…)

    Quellcode

    1. var dataArray = array()
    2. for element in workdata {
    3. var newData = mydata(id: element[0].string, name: element[1].string, description: element[2].string)
    4. dataArray.add(newData)
    5. }
    6. self.mydata =dataArray

    So schaufelst Du alle Elemente nacheinander in ein Array und setzt dieses Array dann halt am Ende der Schleife.

    Natürlich könntest Du das abkürzen.

    Quellcode

    1. for element in workdata {
    2. var newData = mydata(id: element[0].string, name: element[1].string, description: element[2].string)
    3. self.mydata.add(newData)
    4. }


    Solltest Du aber lassen, weil es zu einer Inkonsistenz Exception kommen kann, wenn Du an anderer Stelle gerade über self.mydata iterierst.

    t-no schrieb:

    Noch ein klares "Nein" zu NSDictionary.
    Erstens ist das eh "Legacy" für Swift, vor allem imho aber schlechter Stil:
    Daten "von aussen" darf man nicht trauen, und in einem NSDictionary kann fast alles drin stecken (oder auch fehlen...).

    Wait. Wat?

    Klar, man sollte generell die Finger von NS* Zeugs in Swift lassen, aber Dictionaries zu verteufeln kann eigentlich nur von starren Compilerfreaks kommen.
    Ich gebe Dir insofern recht als dass man die Finger von dynamischem Zeugs in starrem Krams lassen sollte.

    Aber in einem NSDictionary kann eben nur dann fast alles drin stecken oder fehlen, wenn man es scheiße programmiert.
    In einem Swift Dictionary kann übrigens auch fast alles drin stecken oder fehlen, wenn man es scheiße programmiert…

    t-no schrieb:

    Mit Objective-C war das Anlegen einer neuen Klasse ja ziemlich hoher Aufwand, bei Swift fällt diese "Entschuldigung" für Dictionaries aber weitgehend weg (außerdem gibt's endlich Tupel, wenn der Aufwand immer noch zu groß empfunden wird).

    Wait. Wat?
    Hoher Aufwand? Drei mal klicken war hoher Aufwand?

    Ja, die Erstellung eines übersichtlich zusammengefassten öffentlichen Header Files mag auf den ersten Blick nach dem Erstellen von zwei Dateien aussehen.
    Aber mal ehrlich: ob ich mir in einer Datei über public/private/protected Gedanken mache oder in zwei Dateien, der Aufwandsunterschied ist doch eher nicht existent.
    «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

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

  • t-no schrieb:

    Noch ein klares "Nein" zu NSDictionary.
    Erstens ist das eh "Legacy" für Swift, vor allem imho aber schlechter Stil:
    Daten "von aussen" darf man nicht trauen, und in einem NSDictionary kann fast alles drin stecken (oder auch fehlen...).

    Mit Objective-C war das Anlegen einer neuen Klasse ja ziemlich hoher Aufwand, bei Swift fällt diese "Entschuldigung" für Dictionaries aber weitgehend weg (außerdem gibt's endlich Tupel, wenn der Aufwand immer noch zu groß empfunden wird).
    Immer diese Flamewars mit FUD.

    Wenn man Daten von außen nicht trauen darf, was richtig ist, bedarf es Code, der sie überprüft. Auch in Basic.
    Wenn man Daten von außen überprüft hat, kann in dem Container-Objekt nicht fast alles drinstecken, sondern nur Geprüftes.

    Wie sich genau der Aufwand verringert, ist mir auch unklar. Weil ich keine Deklaration im Header brauche? Ich fand diese Sammlung eigentlich immer Ausfand verringernd. Wie dem auch sei: Die Beschränkung auf drei Zugriffsebenen ist wohl mal wieder der Flexibilität von Swift geschuldet. Ich habe jedenfalls immer wieder bei Frameworks 4 Access-Level:

    Nutzer des Frameworks
    Framework selbst
    Subklassen
    Nur Implementierer

    Wie macht man das mit Swift?
    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"?
  • Marco Feltmann schrieb:

    man sollte generell die Finger von NS* Zeugs in Swift lassen

    mehr sage ich auch nicht - Dictionaries haben noch reichlich Daseinsberechtigung, selbst "[Hashable:Any]"

    Marco Feltmann schrieb:

    Hoher Aufwand? Drei mal klicken war hoher Aufwand?

    Für kleine Datenklassen ist Objective-C definitiv unangenehm viel Boilerplate, und das Eingabegerät wechseln ist jedes Mal lästig (und sogar ungesund):
    Header aufmachen, Klasse, Methoden und Properties deklarieren, dann zur Implementation die ganzen Deklarationen leicht verändert noch mal tippen...
    Allein schon wegen des Konstruktors ist das viel stupide Arbeit, wie getter/setter von Hand schreiben:

    Quellcode

    1. struct User {
    2. let name = "Anon"
    3. let age = 18
    4. let rating = 100
    5. let street = "unknown"
    6. let city = "unknown"
    7. }

    Bau eine Klasse mit der selben Funktionalität mal in Objective-C nach - das mach absolut keinen Spaß.
    Solche Dinge halte ich für weit wichtiger als theoretische Performance-Vorteile oder bessere Typüberprüfung.
  • Wie tippe ich denn die Properties noch einmal leicht verändert in der Implementierung?

    Die beiden Klassenfiles sind vorausgefüllt bereits vorhanden. Für einen einfachen Container muss ich in der Implementierung gar nichts wiederholen.
    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"?
  • t-no schrieb:

    Marco Feltmann schrieb:

    man sollte generell die Finger von NS* Zeugs in Swift lassen

    mehr sage ich auch nicht - Dictionaries haben noch reichlich Daseinsberechtigung, selbst "[Hashable:Any]"

    Marco Feltmann schrieb:

    Hoher Aufwand? Drei mal klicken war hoher Aufwand?

    Für kleine Datenklassen ist Objective-C definitiv unangenehm viel Boilerplate, und das Eingabegerät wechseln ist jedes Mal lästig (und sogar ungesund):
    Header aufmachen, Klasse, Methoden und Properties deklarieren, dann zur Implementation die ganzen Deklarationen leicht verändert noch mal tippen...
    Allein schon wegen des Konstruktors ist das viel stupide Arbeit, wie getter/setter von Hand schreiben:

    Quellcode

    1. struct User {
    2. let name = "Anon"
    3. let age = 18
    4. let rating = 100
    5. let street = "unknown"
    6. let city = "unknown"
    7. }

    Bau eine Klasse mit der selben Funktionalität mal in Objective-C nach - das mach absolut keinen Spaß.
    Solche Dinge halte ich für weit wichtiger als theoretische Performance-Vorteile oder bessere Typüberprüfung.


    öm bitte:

    Quellcode

    1. ​@interface User : NSObject
    2. @property NSString *name;
    3. @property int age;
    4. @property MyRatingType rating; // oder von mir aus int oder was auch immer.
    5. @property NSString *street;
    6. @property NSString *city;
    7. @end
    8. @implementation User
    9. @end


    fertig.
  • Nur damit ich das richtig verstehe:
    es wird sich darüber beschwert, dass man Properties nur mit Tipperei mit Standardwerten belegen kann, welche von den vom Compiler vorbelegten Standardwerten abweicht.

    Dazu fällt mir dann aber auch nix mehr ein…
    «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