I'm creating a UITableView that will display this response in every cell. The problem is, I do not know how to parse this response to the model.
Here is the response from the api
[
"electronics",
"jewelery",
"men's clothing",
"women's clothing"
]
Here is the code for the the ViewController
class HomeViewController: UIViewController {
@IBOutlet var tableView: UITableView!
var category: [Category] = []
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
guard let url = URL(string: "\(Constants.url.baseUrl)\(Constants.url.category)") else {
return
}
AF.request(url).responseDecodable(of: [Category].self) { response in
guard let categories = response.value else {
return
}
DispatchQueue.main.async { [weak self] in
self?.tableView.reloadData()
}
}
}
}
extension HomeViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("category count", category.count)
return category.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: Constants.identifiers.categoryTableViewCell) as? CategoryTableViewCell else{
return UITableViewCell()
}
cell.configureTableViewCell(with: self.category[indexPath.row])
return cell
}
}
Here is my model
struct Category: Codable {
}
I would greatly appreciate any help. Thank you in advanced!
CodePudding user response:
Here is the answer to your problem...
So your model class will look something like this :
import Foundation
struct Category: Codable {
enum CodingKeys: String, CodingKey {
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
}
}
Now you can use this as one of the three following ways to parse the data :
1.Using Codable Mapping :
let url = URL(string: "http://www.google.com")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
let jsonDecoder = JSONDecoder()
let responseModel = try jsonDecoder.decode(Category.self, from: data!)
}
task.resume()
2.Using ObjectMapper
// Convert JSON String to Model
let responseModel = Mapper<Category>().map(JSONString: JSONString)
// Create JSON String from Model
let JSONString = Mapper().toJSONString(responseModel, prettyPrint: true)
3.Using Dictionary Mapping
let url = URL(string: "http://www.google.com")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
let someDictionaryFromJSON = try JSONSerialization.jsonObject(with:
data, options: .allowFragments) as! [String: Any]
let category = Category(someDictionaryFromJSON)
}
task.resume()
CodePudding user response:
Here is your answer
guard let url = URL(string: "https://fakestoreapi.com/products/categories") else {
return
}
AF.request(url).responseData(completionHandler: { response in
guard let responseData = response.data else {
return
}
let categoriesData = try? JSONDecoder().decode(Categories.self, from: responseData)
print(categoriesData!)
})
Parsing
typealias Categories = [String]
Response
Here in your case, your response returns only a string array so can't need to create the Model Class for this you can achieve by
typealiasvariable
If there are any other more objects in your response then you can do like this
struct Category: Codable {
let id: Int?
var name: String?
enum CodingKeys: String, CodingKey {
case id = "ID"
case name = "Name"
}
init(from decoder: Decoder) throws
{
let values = try decoder.container(keyedBy: CodingKeys.self)
id = try? values.decode(Int.self, forKey: .id)
name = try? values.decode(String.self, forKey: .name)
}
}
guard let url = URL(string: "https://fakestoreapi.com/products/categories") else {
return
}
AF.request(url).responseData(completionHandler: { response in
guard let responseData = response.data else {
return
}
let categoryData = try? JSONDecoder().decode(Category.self, from: responseData)
print(categoryData.id)
print(categoryData.name)
})

