JSON Paktet decoden

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

  • Okay also ich habe gesehen das mir ein kleiner Fehler unterlaufen ist. Ich habe ja mein JSON-Paket verbessert bzw. übersichtlicher gemacht und ich hatte noch das alte verwendet was jedoch nicht mehr lauffähig ist. Also ich bekommen jetzt bei print(self.items) mein JSON-Paket in der Console ausgespuckt.

    Mein Code schaut aktuell so aus:

    Quellcode

    1. import UIKit
    2. struct RootElement: Codable {
    3. var data: [QuestionInfo]?
    4. var status: String
    5. }
    6. struct QuestionInfo: Codable {
    7. var title: String
    8. var id: String
    9. var username: String
    10. enum CodingKeys: String, CodingKey {
    11. case title = "question_title"
    12. case id = "user_id"
    13. case username = "user_username"
    14. }
    15. init(from decoder: Decoder) throws {
    16. let valueContainer = try decoder.container(keyedBy: CodingKeys.self)
    17. self.title = try valueContainer.decode(String.self, forKey: CodingKeys.title)
    18. self.id = try valueContainer.decode(String.self, forKey: CodingKeys.id)
    19. self.username = try valueContainer.decode(String.self, forKey: CodingKeys.username)
    20. print("\(username) mit der ID \(id), sagt \(title)")
    21. }
    22. }
    23. extension URL {
    24. func withQueries(_ queries: [String: String]) -> URL? {
    25. var components = URLComponents(url: self, resolvingAgainstBaseURL: true)
    26. components?.queryItems = queries.compactMap{ URLQueryItem(name: $0.0, value: $0.1) }
    27. return components?.url
    28. }
    29. }
    30. class TableViewController: UITableViewController {
    31. @IBOutlet var profileTableView: UITableView!
    32. var items = [RootElement]()
    33. override func viewDidLoad() {
    34. super.viewDidLoad()
    35. let baseURL = URL(string: "https://valapi.cedsoft.de/v0.1/questions.php")!
    36. let query: [String: String] = [
    37. "api_key": "DEMO_KEY",
    38. ]
    39. let url = baseURL.withQueries(query)!
    40. let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
    41. let decoder = JSONDecoder()
    42. let data = data!
    43. self.items = [try! decoder.decode(RootElement.self, from: data)]
    44. //let jsonData = try! JSONSerialization.jsonObject(with: data, options: [])
    45. //self.items = jsonData as! [String: String]
    46. print(self.items)
    47. }
    48. task.resume()
    49. }
    50. override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    51. //return items.count
    52. return 1
    53. }
    54. override func numberOfSections(in tableView: UITableView) -> Int {
    55. return 1
    56. }
    57. override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    58. let cell = tableView.dequeueReusableCell(withIdentifier: "UserLine", for: indexPath) as! UserTableViewCell
    59. return cell
    60. }
    61. }
    Alles anzeigen

    So nun hatte ich probiert in der cellForRowAt Funktion mein Label mit einem Wert zu füllen. Ich wollte mir bspw. alle Usernamen von oben nach unten anzeigen lassen. Habe das ganze dann so probiert:


    Quellcode

    1. override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    2. let cell = tableView.dequeueReusableCell(withIdentifier: "UserLine", for: indexPath) as! UserTableViewCell
    3. let countArray = items[indexPath.row]
    4. cell.titleLabel.text = countArray.data?[0].username
    5. return cell
    6. }
    Doch leider bleiben meine TableViewCells leer. Zudem ich mit der Art und Weise mit der ich das hier probiert habe, wahrscheinlich ohnehin nicht alle Namen auslesen hätte können sondern lediglich nur einen. Das Problem ist das ich bei data einen Index setze, was jedoch notwendig ist da ich sonst die Fehlermeldung bekomme das data keinen Member "username" beinhaltet. Aber wie gesagt mir wird das JSON-Paket angezeigt was bedeuten muss dass das decodieren funktioniert. Was mache ich falsch ?
  • Versuche es mal so:

    C-Quellcode

    1. import UIKit
    2. struct RootElement: Codable {
    3. var data: [QuestionInfo]?
    4. var status: String
    5. }
    6. struct QuestionInfo: Codable {
    7. var title: String
    8. var id: String
    9. var username: String
    10. enum CodingKeys: String, CodingKey {
    11. case title = "question_title"
    12. case id = "user_id"
    13. case username = "user_username"
    14. }
    15. init(from decoder: Decoder) throws {
    16. let valueContainer = try decoder.container(keyedBy: CodingKeys.self)
    17. self.title = try valueContainer.decode(String.self, forKey: CodingKeys.title)
    18. self.id = try valueContainer.decode(String.self, forKey: CodingKeys.id)
    19. self.username = try valueContainer.decode(String.self, forKey: CodingKeys.username)
    20. print("\(username) mit der ID \(id), sagt \(title)")
    21. }
    22. }
    23. extension URL {
    24. func withQueries(_ queries: [String: String]) -> URL? {
    25. var components = URLComponents(url: self, resolvingAgainstBaseURL: true)
    26. components?.queryItems = queries.compactMap{ URLQueryItem(name: $0.0, value: $0.1) }
    27. return components?.url
    28. }
    29. }
    30. class TableViewController: UITableViewController {
    31. @IBOutlet var profileTableView: UITableView!
    32. var items: RootElement?
    33. override func viewDidLoad() {
    34. super.viewDidLoad()
    35. let baseURL = URL(string: "https://valapi.cedsoft.de/v0.1/questions.php")!
    36. let query: [String: String] = [
    37. "api_key": "DEMO_KEY",
    38. ]
    39. let url = baseURL.withQueries(query)!
    40. let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
    41. let decoder = JSONDecoder()
    42. let data = data!
    43. self.items = try! decoder.decode(RootElement.self, from: data)
    44. //let jsonData = try! JSONSerialization.jsonObject(with: data, options: [])
    45. //self.items = jsonData as! [String: String]
    46. print(self.items)
    47. self.profileTableView.reloadData()
    48. }
    49. task.resume()
    50. }
    51. override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    52. //return items.count
    53. return self.items?.data?.count
    54. }
    55. override func numberOfSections(in tableView: UITableView) -> Int {
    56. return 1
    57. }
    58. override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    59. let cell = tableView.dequeueReusableCell(withIdentifier: "UserLine", for: indexPath) as! UserTableViewCell
    60. let questionInfo = self.items?.data?[indexPath.row]
    61. cell.titleLabel.text = questionInfo?.username
    62. return cell
    63. }
    64. }
    Alles anzeigen
    Ich hoffe der Source Code compiliert, da ich kein Swift kann. Anderenfalls musst Du die ggf. vorhanden Fehler fixen. ;)

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von MCDan () aus folgendem Grund: Source Code geändert!

  • Okay also ich hab das jetzt mal ausprobiert und bekomme dann zwei mal den selben Fehler: Value of type '[RootElement]' has no member 'data'
    für folgende zwei Zeilen:
    return self.items.data.count

    und
    let questionInfo = items.data[indexPath.row]

    Wie du gesagt hast, habe ich dann versucht die entstandenen Fehler zu beheben in dem ich aus den beiden Zeilen jeweils das hier gemacht habe
    return (self.items[0].data?.count)!

    und
    let questionInfo = items[0].data![indexPath.row]

    Wenn ich dann versuche die App zu starten dann bekommen ich für diese Zeile return (self.items[0].data?.count)!, den Fehler:
    Thread 1: Fatal error: Index out of range

    Zufällig ne Ahnung wie der Fehler zustande kommt ? :/
  • MCDan schrieb:

    Ok, wenn items dadurch ein Array wird, dann ist es klar warum der Code nicht funktioniert. items muss ja einfach nur ein einzelnes RootElement sein. ;)
    Nene stimmt schon so.

    Ändere mal

    Quellcode

    1. self.items = [try! decoder.decode(RootElement.self, from: data)]

    Zu

    Quellcode

    1. self.items = try! decoder.decode([RootElement].self, from: data)

    Und bitte keine !, nutz Optionals, if let und guard let.
  • matz schrieb:

    MCDan schrieb:

    Ok, wenn items dadurch ein Array wird, dann ist es klar warum der Code nicht funktioniert. items muss ja einfach nur ein einzelnes RootElement sein. ;)
    Nene stimmt schon so.

    Hm, dann hast Du mehr Infos über den Aufbau des aktuellen JSON als ich. Bei der zuletzt geposteten Version ist der Root Datentyp definitiv ein Objekt und kein Array. ;)

    Warum sollte man aus dem Root Datentyp Objekt beim Decodieren also ein Array machen? ?(
  • Also erstmal tut es mir leid das ich mich nicht gemeldet habe. Bin gerade im Urlaub und deswegen fehlt mir an manchen Stellen leider die Zeit immer direkt zu antworten :/

    Ich habe den Source Code also mal ausprobiert musste ihn aber in einer Zeile ändern. Der Code sieht jetzt so aus:

    Quellcode

    1. import UIKit
    2. struct RootElement: Codable {
    3. var data: [QuestionInfo]?
    4. var status: String
    5. }
    6. struct QuestionInfo: Codable {
    7. var title: String
    8. var id: String
    9. var username: String
    10. enum CodingKeys: String, CodingKey {
    11. case title = "question_title"
    12. case id = "user_id"
    13. case username = "user_username"
    14. }
    15. init(from decoder: Decoder) throws {
    16. let valueContainer = try decoder.container(keyedBy: CodingKeys.self)
    17. self.title = try valueContainer.decode(String.self, forKey: CodingKeys.title)
    18. self.id = try valueContainer.decode(String.self, forKey: CodingKeys.id)
    19. self.username = try valueContainer.decode(String.self, forKey: CodingKeys.username)
    20. print("\(username) mit der ID \(id), sagt \(title)")
    21. }
    22. }
    23. extension URL {
    24. func withQueries(_ queries: [String: String]) -> URL? {
    25. var components = URLComponents(url: self, resolvingAgainstBaseURL: true)
    26. components?.queryItems = queries.compactMap{ URLQueryItem(name: $0.0, value: $0.1) }
    27. return components?.url
    28. }
    29. }
    30. class TableViewController: UITableViewController {
    31. @IBOutlet var profileTableView: UITableView!
    32. var items: RootElement?
    33. override func viewDidLoad() {
    34. super.viewDidLoad()
    35. let baseURL = URL(string: "https://valapi.cedsoft.de/v0.1/questions.php")!
    36. let query: [String: String] = [
    37. "api_key": "DEMO_KEY",
    38. ]
    39. let url = baseURL.withQueries(query)!
    40. let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
    41. let decoder = JSONDecoder()
    42. let data = data!
    43. self.items = try! decoder.decode(RootElement.self, from: data)
    44. //let jsonData = try! JSONSerialization.jsonObject(with: data, options: [])
    45. //self.items = jsonData as! [String: String]
    46. print(self.items as Any)
    47. self.profileTableView.reloadData()
    48. }
    49. task.resume()
    50. }
    51. override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    52. //return items.count
    53. return (self.items?.data?.count)!
    54. }
    55. override func numberOfSections(in tableView: UITableView) -> Int {
    56. return 1
    57. }
    58. override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    59. let cell = tableView.dequeueReusableCell(withIdentifier: "UserLine", for: indexPath) as! UserTableViewCell
    60. let questionInfo = self.items?.data?[indexPath.row]
    61. cell.titleLabel.text = questionInfo?.username
    62. return cell
    63. }
    64. }
    Alles anzeigen
    Die Zeile die ich ändern musste ist self.items?.data?.count und zwar wie ihr sehen könnt zu (self.items?.data?.count)!, anders wäre es nicht gegangen. Dabei tritt aber ein Fehler auf wenn ich die App versuche zu starten, nämlich:

    Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

    Das bedeutet also das items nach wie vor leer ist, was ich einfach nicht verstehe...

    Zu @matz Beitrag auch noch. Du hast recht, items ist ein Array von RootElementen. Das bedeutet darin enthalten sind einmal "status" und "data". Was mich in dem Fall interessiert ist data. Anhand des JSON-Pakets sieht man das auch data ein Array ist das die für mich interessanten Infos beinhaltet. Ich hoffe es wird deutlich was ich meine. Hier nochmal das JSON-Paket:


    Quellcode

    1. {"status":"ok","time":1532367823,"data":[{"user_id":"29","user_username":"pascalpru","user_profilepicture":"upload2\/profilbild_user29.jpg","question_id":"1","question_title":"Ja Moin","question_pictures":["GahNiem0","iePh5che","Ooroo7oo","up6pho4A"],"question_date":"1530094596"},{"user_id":"32","user_username":"JoELCHAPO","user_profilepicture":"upload2\/profilbild_user32.png","question_id":"2","question_title":"Was geht","question_pictures":["Oodei3pu","ohreiTe5","reec2Bai"],"question_date":"1530094734"},{"user_id":"34","user_username":"MaxMusti","user_profilepicture":"upload2\/profilbild_user34.png","question_id":"3","question_title":"Valence ist cool","question_pictures":["Ohbii3mu","thae0Eej"],"question_date":"1530094877"},{"user_id":"35","user_username":"philpru98","user_profilepicture":"upload2\/profilbild_user35.png","question_id":"4","question_title":"Coole Schuhe","question_pictures":["Taebui9N","saeSh6ip","up6pho4A"],"question_date":"1530094887"},{"user_id":"36","user_username":"Test","user_profilepicture":"","question_id":"5","question_title":"Welcher Schrank?","question_pictures":["Ejohjuo8","eiHeePh7","naiza3Fe","Woh0yoof"],"question_date":"1530094897"},{"user_id":"37","user_username":"Sonja","user_profilepicture":"","question_id":"6","question_title":"Wo soll ich hin gehen?","question_pictures":["tae9Daet","Aenie3oh"],"question_date":"1530094907"},{"user_id":"38","user_username":"Kalle","user_profilepicture":"","question_id":"7","question_title":"Welchen Urlaub?","question_pictures":["pheWohs6","eiph1Eeg"],"question_date":"1530095252"},{"user_id":"39","user_username":"Manny","user_profilepicture":"","question_id":"8","question_title":"Handy?","question_pictures":["oom0Nu0n","xee7Thah","ak0EeP1U"],"question_date":"1530095262"},{"user_id":"40","user_username":"Tobi","user_profilepicture":"","question_id":"9","question_title":"Was ist geiler?","question_pictures":["uQu0aigh","ienej3Wi","FahH2ohv","yohThie1","ahKai2Ro"],"question_date":"1530095360"},{"user_id":"41","user_username":"derced","user_profilepicture":null,"question_id":"10","question_title":"Was soll ich essen?","question_pictures":["Cexom0ii","ix8IkeiR","Quughu2i","ulaeCoR7"],"question_date":"1530095367"}]}

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

  • Ohne dir auf den Schlips treten zu wollen, aber hättet du die Beiträge zu if let, guard beherzigt wäre es ohne

    Quellcode

    1. (self.items?.data?.count)!
    gegangen.

    Ich würde dir empfehlen deinen Code zum Parsen der Daten (nur das JSON) in einen Playground auszulagern um sicher zu gehen das dort alles funktioniert. Wenn das klappt solltest du dir genauer ansehen wie das laden und anzeigen von Daten in der asynchronen Welt funktioniert.
    Das Herz besitzt Gründe, die die Vernunft nicht kennt.
  • Ich sagte ja schon, mit Swift stehe ich noch auf dem Kriegsfuß und im Vergleich zu Objective-C braucht man auch mal etwas mehr Zeilen für das gleiche Ergebnis.

    C-Quellcode

    1. import UIKit
    2. struct RootElement: Codable {
    3. var data: [QuestionInfo]?
    4. var status: String
    5. }
    6. struct QuestionInfo: Codable {
    7. var title: String
    8. var id: String
    9. var username: String
    10. enum CodingKeys: String, CodingKey {
    11. case title = "question_title"
    12. case id = "user_id"
    13. case username = "user_username"
    14. }
    15. init(from decoder: Decoder) throws {
    16. let valueContainer = try decoder.container(keyedBy: CodingKeys.self)
    17. self.title = try valueContainer.decode(String.self, forKey: CodingKeys.title)
    18. self.id = try valueContainer.decode(String.self, forKey: CodingKeys.id)
    19. self.username = try valueContainer.decode(String.self, forKey: CodingKeys.username)
    20. print("\(username) mit der ID \(id), sagt \(title)")
    21. }
    22. }
    23. extension URL {
    24. func withQueries(_ queries: [String: String]) -> URL? {
    25. var components = URLComponents(url: self, resolvingAgainstBaseURL: true)
    26. components?.queryItems = queries.compactMap{ URLQueryItem(name: $0.0, value: $0.1) }
    27. return components?.url
    28. }
    29. }
    30. class TableViewController: UITableViewController {
    31. @IBOutlet var profileTableView: UITableView!
    32. var items: RootElement?
    33. override func viewDidLoad() {
    34. super.viewDidLoad()
    35. let baseURL = URL(string: "https://valapi.cedsoft.de/v0.1/questions.php")!
    36. let query: [String: String] = [
    37. "api_key": "DEMO_KEY",
    38. ]
    39. let url = baseURL.withQueries(query)!
    40. let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
    41. let decoder = JSONDecoder()
    42. let data = data!
    43. self.items = try! decoder.decode(RootElement.self, from: data)
    44. //let jsonData = try! JSONSerialization.jsonObject(with: data, options: [])
    45. //self.items = jsonData as! [String: String]
    46. print(self.items as Any)
    47. self.profileTableView.reloadData()
    48. }
    49. task.resume()
    50. }
    51. override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    52. //return items.count
    53. if let numberOfRowsInSection = self.items?.data?.count {
    54. return numberOfRowsInSection
    55. } else {
    56. return 0
    57. )
    58. }
    59. override func numberOfSections(in tableView: UITableView) -> Int {
    60. return 1
    61. }
    62. override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    63. let cell = tableView.dequeueReusableCell(withIdentifier: "UserLine", for: indexPath) as! UserTableViewCell
    64. if let questionInfo = self.items?.data?[indexPath.row] {
    65. cell.titleLabel.text = questionInfo.username
    66. }
    67. return cell
    68. }
    69. }
    Alles anzeigen
    Sollte dies in Swift, also speziell self.items?.data?.count, doch einfacher gehen, dann würde ich mich über die Lösung inkl. Erklärung freuen. ;)

    @ThisIsBeat Wieso sollte items ein Array von RootElementen sein? In Deinem JSON ist der Root Datentyp doch eindeutig ein Objekt (also {}) und kein Array (also []).

    items ist zu Beginn deshalb leer bzw. nil weil dataTask(with:completionHandler:) asynchron ist und der completionHandler erst aufgerufen wird, wenn die Daten geladen wurden. Zwischenzeitlich versucht allerdings der TableView seinen Inhalt anzuzeigen. Daher fehlte in dem completionHandler auch ein reloadData(), damit der TableView das geladene und decodierte JSON anzeigt.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von MCDan ()

  • MCDan schrieb:

    Sollte dies in Swift, also speziell self.items?.data?.count, doch einfacher gehen, dann würde ich mich über die Lösung inkl. Erklärung freuen.
    Ich habe den Code mal optimiert und die Stellen kommentiert:

    C-Quellcode

    1. import UIKit
    2. struct RootElement: Codable {
    3. var data = [QuestionInfo]() // Hier Defaultwerte gesetzt
    4. var status = "" // macht die Nutzung unten leichter
    5. }
    6. struct QuestionInfo: Codable {
    7. var title: String
    8. var id: String
    9. var username: String
    10. enum CodingKeys: String, CodingKey {
    11. case title = "question_title"
    12. case id = "user_id"
    13. case username = "user_username"
    14. }
    15. // init(from:) Methode wird nicht benötigt, macht der Compiler automatisch
    16. }
    17. extension URL {
    18. func withQueries(_ queries: [String: String]) -> URL? {
    19. var components = URLComponents(url: self, resolvingAgainstBaseURL: true)
    20. components?.queryItems = queries.map{ URLQueryItem(name: $0.0, value: $0.1) }
    21. return components?.url
    22. }
    23. }
    24. class TableViewController: UITableViewController {
    25. @IBOutlet var profileTableView: UITableView!
    26. var items: RootElement = RootElement() // Defaultwert gesetzt, damit keine Optional-Prüfung mehr
    27. override func viewDidLoad() {
    28. super.viewDidLoad()
    29. let baseURL = URL(string: "https://valapi.cedsoft.de/v0.1/questions.php")!
    30. let query: [String: String] = [
    31. "api_key": "DEMO_KEY",
    32. ]
    33. guard let url = baseURL.withQueries(query) else { return }
    34. let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
    35. guard let data = data else { return } // wenn keine Daten da sind, sind wir hier schon fertig
    36. let decoder = JSONDecoder()
    37. self.items = (try? decoder.decode(RootElement.self, from: data)) ?? RootElement() // Bei fehlgeschlagener Decodierung, Defaultwert setzen statt crashen!
    38. print(self.items as Any)
    39. self.profileTableView.reloadData()
    40. }
    41. task.resume()
    42. }
    43. override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    44. return items.data.count // Da wir oben die Optionals beseitigt haben, ist das nun ein Einzeiler
    45. }
    46. override func numberOfSections(in tableView: UITableView) -> Int {
    47. return 1 // entspricht dem Defaultwert, Methode eigentlich überflüssig
    48. }
    49. override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    50. guard let cell = tableView.dequeueReusableCell(withIdentifier: "UserLine", for: indexPath) as? UserTableViewCell else { fatalError() }
    51. cell.titleLabel.text = items.data[indexPath.row].username // Ohne Optionals verkürzt sich so einiges
    52. return cell
    53. }
    54. }
    Alles anzeigen
  • @MCDan Oh ja natürlich, du hast recht. Ich bin da an der Stelle durcheinander gekommen bzw. meinte ich eher das die Variable data im RootElement ein Array war. Wie gesagt ich bin durcheinander gekommen und meinte dabei was anderes. Hab dazu auch nochmal was im Netzt gefunden was bestätigt das du Recht hast:
    „Curly brackets { } encapsulate a dictionary of keys and values.
    Square brackets [ ] encapsulate an array.
    Text inside of quotation marks " " are string values.
    Numbers and Booleans are written without quotation marks.“

    also verstehe ich das richtig das reloadData dazu da ist um die TableView mit den Daten zu füllen und im gleichen Zug dann auch sicherzustellen dass der asynchrone dataTask auf Daten zugreifen kann wenn er soweit ist ?
  • Michael schrieb:

    Ich habe den Code mal optimiert und die Stellen kommentiert:
    Also der Code funktioniert :D Echt super das es endlich geklappt hat. An der Stelle auch ein riesen Dankeschön an alle die mir bei meinem Problem bis hier hin geholfen haben. Doch jetzt geht es mir darum zu verstehen warum es jetzt geklappt hat und davor eben nicht. Ich habe deinen Code @Michael mal eben mit meiner letzten Version verglichen und dazu habe ich ein paar Fragen :)

    Also einmal hast du die Variable items zu folgendem geändert. Ich meine mit dem ersten RootElement in items, gibst du den Type an. RootElement() ist dann der Defaultwert. Doch warum habe ich dann keine Optional-Prüfung mehr ?
    var items: RootElement = RootElement() // Defaultwert gesetzt, damit keine Optional-Prüfung mehr

    Dann sehe ich hast du die Optionals für let url und let data mit Guard gelöst und diese Zeile geschrieben:
    self.items = (try? decoder.decode(RootElement.self, from: data)) ?? RootElement()

    Du hast ja in dem Kommentar dazu geschrieben das RootElement im Fall der Fälle als Defaultwert dient. Doch was genau ? Bezieht sich vielleicht auch ein wenig auf meine erste Frage.

    Naja aber das war es dann eigentlich auch schon im großen und ganzen oder nicht. Also woran ist es dann im wesentlichen bei mir gescheitert ? Daran das ich Optionals verwendet habe, es durch den asynchronen dataTask keine greifbaren Daten gab und die App dann gecrasht ist ?

    Und dann habe ich zu guter letzt noch eine Meldung in Lila bei Xcode bekommen, nämlich:
    UITableView.reloadData() must be used from main thread only
    Ich habe bereits probiert das an die Stelle zu schieben in dem task.resume() auch steht weil ich dachte dass das mit dem main thread gemeint ist, doch dann funktioniert es leider nicht mehr. Was soll ich also mit der Meldung tun ?

    Sorry das ich so viel frage aber ich hab noch viel in Swift zu lernen und möchte besser werden damit ich immer mehr Probleme eigenständig lösen kann :D
  • ThisIsBeat schrieb:

    Doch warum habe ich dann keine Optional-Prüfung mehr ?
    Weil du entweder deine Items vom Webservice hast oder ein "leeres" RootElement was dann als default initialisiert wird.


    ThisIsBeat schrieb:

    UITableView.reloadData() must be used from main thread only
    Ja, schön das Xcode das anzeigt :)

    Du kannst es wieder an die Stelle packen wo es vorher war und hiermit im Mainthread machen.

    Quellcode

    1. DispatchQueue.main.async {
    2. self.profileTableView.reloadData()
    3. }
    Sich hier einzulesen schadet sicherlich nicht

    developer.apple.com/library/ar…eues/OperationQueues.html