Home > front end >  Swift parsing JSON into Table View doesnt work
Swift parsing JSON into Table View doesnt work

Time:04-27

Hi I have problems to read the Json Data into the TableView. Can anybody help me, its my first time working with it. I know I am doing something wrong, but I cant finde the Solution for my JSON File cause in the Internet they use simple ones..

Here is my JSON:

{
    "data":[
        {
            "title": "Brot",
            "desc":[
                {
                    "Name": "Roggenschrot- und Roggenvollkornbrot",
                    "Menge": "Gramm",
                    "Kalorie": "2",
                    "Energiedichte": "Gelb"
                },
                {
                    "Name": "Weizenschrot- und Weizenvollkornbrot",
                    "Menge": "Gramm",
                    "Kalorie": "2",
                    "Energiedichte": "Gelb"
                },
                {
                    "Name": "Weizenschrot- und Weizenvollkornbrot",
                    "Menge": "Gramm",
                    "Kalorie": "2",
                    "Energiedichte": "Gelb"
                },
            ]
        }
    ]
}

Here is my tableView

import UIKit

class EseenTagebuchTableViewController: UITableViewController {
    
    var result: Result?
    var resultItem: ResultItem?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        parseJSON()

    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return result?.data.count ?? 0
    }
    
    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return result?.data[section].title
    }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        if let result = result {
            return result.data.count
        }
        return 0
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let text = resultItem?.desc?[indexPath.section].Name?[indexPath.row]
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = text
        return cell
    }
    

    private func parseJSON() {
        guard let path = Bundle.main.path(forResource: "Ernahrungstagebuch", ofType: "json") else {
            return
        }
        let url = URL(fileURLWithPath: path)
        
       
        
        do {
            let jsonData = try Data(contentsOf: url)
            result = try JSONDecoder().decode(Result.self, from: jsonData)
            return
        }
        catch {
            print("Error: \(error)")
        }
    }

}

And here are my Model 1 and after my Model 2

import Foundation

struct Result: Codable {
    let data: [ResultItem]
   
}

struct ResultItem: Codable {
    let title: String
    let desc: [descItems]?
}

Model 2

import Foundation

struct descItems: Codable {
    let Name: String?
    let Menge: String?
    let Kalorie: Int?
    let Energiedichte: String?
}

What am I doing wrong?

CodePudding user response:

you can also use json parse below code:

func parseJSON() {
let path =  Bundle.main.path(forResource: "Ernahrungstagebuch", ofType: "json")
let jsonData = try? NSData(contentsOfFile: path!, options: NSData.ReadingOptions.mappedIfSafe)
let jsonResult: NSDictionary = try! (JSONSerialization.jsonObject(with: jsonData! as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary)!

if let data = jsonResult["data"] as? [[String:Any]] {
    self.arrPlan = data.map{Day(JSON: $0)!}
    //            print(arrPlan)
    
}

}

Try to this code for get data array object and after reload tableview Data.

CodePudding user response:

You can use this extension to parse json.

import Foundation

extension Bundle {
    func decode<T: Decodable>(_ type: T.Type, from file: String, dateDecodingStrategy: JSONDecoder.DateDecodingStrategy = .deferredToDate, keyDecodingStrategy: JSONDecoder.KeyDecodingStrategy = .useDefaultKeys) -> T {
        guard let url = self.url(forResource: file, withExtension: nil) else {
            fatalError("Failed to locate \(file) in bundle.")
        }

        guard let data = try? Data(contentsOf: url) else {
            fatalError("Failed to load \(file) from bundle.")
        }

        let decoder = JSONDecoder()
        decoder.dateDecodingStrategy = dateDecodingStrategy
        decoder.keyDecodingStrategy = keyDecodingStrategy

        do {
            return try decoder.decode(T.self, from: data)
        } catch DecodingError.keyNotFound(let key, let context) {
            fatalError("Failed to decode \(file) from bundle due to missing key '\(key.stringValue)' not found – \(context.debugDescription)")
        } catch DecodingError.typeMismatch(_, let context) {
            fatalError("Failed to decode \(file) from bundle due to type mismatch – \(context.debugDescription)")
        } catch DecodingError.valueNotFound(let type, let context) {
            fatalError("Failed to decode \(file) from bundle due to missing \(type) value – \(context.debugDescription)")
        } catch DecodingError.dataCorrupted(_) {
            fatalError("Failed to decode \(file) from bundle because it appears to be invalid JSON")
        } catch {
            fatalError("Failed to decode \(file) from bundle: \(error.localizedDescription)")
        }
    }
}

And use it like this:

let incomingData = Bundle.main.decode([Your_Model].self, from: "Your_Json_File_name.json")
  • Related