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")