I am new in parsing JSON. I made a single view application. I got JSON from URL using this function:
func parseData(){
//created URL
guard let requestURL = URL(string: "https://machla.bh/api-category2") else {return }
//creating URLRequest
var request = URLRequest(url: requestURL)
//setting the method to post
request.httpMethod = "POST"
//creating the post parameter by concatenating the keys and values from text field
var postParameters = ""
postParameters += "key=LpfyirxoNOfP8wPns4nZqTw6DQ4wY A2q6yvpKsof6gkYDTykVXSEonTO2VB HE2zRdqrvsyoyMVyRagWtKAtVuOuNs c7QW5KrgbXS8SqPZ7sIDlPEvhBWyo5 NoObAcor3GlO87nRSaFdxhKDRTiBkK 3pFsTQyffzuBdIBiM8zFra6Yh8NbbC QQaratgFFE2hzLouNEIHq88xaSqum1 C0z7g325i3hixT5oLSo5tvhpvvdTJO WohfqGSakeGz7hsAU"
postParameters += "&path=59"
postParameters += "&language_id=1"
//adding the parameters to request body
request.httpBody = postParameters.data(using: .utf8)
//creating a task to send the post request
let session = URLSession.shared
let task = session.dataTask(with: request) { data, response, error in
guard error == nil else {
print("error is \(error!.localizedDescription)")
return
}
guard let data = data else {
print("No data was returned by the request!")
return
}
// print data from request
let str = String(data: data, encoding: .utf8)!
print(str)
for eachFetechedCountry in str
{
let eachCountry=eachFetechedCountry as! [String:Any]
let category = eachCountry["categories"] as! String
let product=eachCountry["products"] as! String
self.fetchcountry.append(Country(categories: category, products: product))
}
self.countryTableView.reloadData()
}
//executing the task
task.resume()
}
I am trying to read categories and products from JSON using following statement in the above function. These statements are not working. How to read categories and products from JSON?
for eachFetechedCountry in str
{
let eachCountry=eachFetechedCountry as! [String:Any]
let category = eachCountry["categories"] as! String
let product=eachCountry["products"] as! String
self.fetchcountry.append(Country(categories: category, products: product))
}
For populating categories and product into table view I created a class named Country
:
class Country{
var product:String
var category:String
init(categories :String, products:String)
{
self.category=categories
self.product=products
}
}
For populating categories and product into table view I coded:
func tableView(_ tableViewr: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = countryTableView.dequeueReusableCell(withIdentifier: "cell")
cell?.textLabel?.text=fetchcountry[indexPath.row].category
cell?.detailTextLabel?.text=fetchcountry[indexPath.row].product
return cell!
}
How to populate categories and product into table view?
From this link you can download sample project for correction?https://drive.google.com/file/d/0B5pNDpbvZ8SnY3RicXpGN1FYbXc/view?usp=sharing
You should use feature of Swift 4 - Decodable protocol.
let task = session.dataTask(with: request) { data, response, error in
guard error == nil else {
print("error is \(error!.localizedDescription)")
return
}
guard let data = data else {
print("No data was returned by the request!")
return
}
do {
let country = try JSONDecoder().decode(Country.self, from: data)
// do what you want here with Country array
// ...
} catch let error {
// catch error and handled it here
}
DispatchQueue.main.async {
self.countryTableView.reloadData()
}
}
//executing the task
task.resume()
Always update tableview in Main thread!!!
And use those structs:
struct Country: Decodable{
var categories: [Category]
}
struct Category: Decodable {
var name: String
var products: [Product]
}
struct Product: Decodable {
var name: String
}