Reputation:
I am trying to group my table view that is being populated from JSON data.
Here is an example of what it looks like:
[{"customer":"Customer1","serial":"34543453",
"rma":"P2384787","model":"M282","manufacturer":"Manufacturer1"},
{"customer":"Customer1","serial":"13213214",
"rma":"P2384787","model":"M384","manufacturer":" Manufacturer1"},
{"customer":"Customer2","serial":"1212121323",
"rma":"P3324787","model":"M384","manufacturer":" Manufacturer1"}]
I would like to group the table view based on the customer name. So in my case, it should look like:
Customer1
34543453 - Manufacturer1 - M282
13213214 - Manufacturer1 - M384
Customer2
1212121323 - Manufacturer1 - M384
NOTE:
The reason there is a line separating the serial manufacturer and model is because of this separator in CustomerViewController.swift:
let titleStr = [item.serial, item.manufacturer, item.model].compactMap { $0 }.joined(separator: " - ")
PortfolioController.swift
import UIKit
class PortfolioController: UITableViewController {
var portfolios = [Portfolios]()
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.title = "Customer"
fetchJSON()
}
func fetchJSON(){
let urlString = "https://www.example.com/example/example.php"
guard let url = URL(string: urlString) else { return }
URLSession.shared.dataTask(with: url) { (data, _, error) in
DispatchQueue.main.async {
if let error = error {
print("Failed to fetch data from url", error)
return
}
guard let data = data else { return }
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
self.portfolios = try decoder.decode([Portfolios].self, from: data)
self.tableView.reloadData()
} catch let jsonError {
print("Failed to decode json", jsonError)
}
}
}.resume()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return portfolios.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellId")
let customer = portfolios[indexPath.row]
//cell.textLabel?.text = customer.serial
let titleStr = [customer.serial, customer.manufacturer, customer.model].compactMap { $0 }.joined(separator: " - ")
print(titleStr)
// Get references to labels of cell
cell.textLabel!.text = titleStr
return cell
}
}
Portfolios.swift
import UIKit
struct Portfolios: Codable {
let customer, serial, rma, model: String
let manufacturer: String
}
Upvotes: 0
Views: 30
Reputation: 100503
1- Create an instance var
var portfoliosDic = [String:[Portfolios]]()
2- Assign it here
let res = try JSONDecoder().decode([Portfolios].self, from: data)
self.portfoliosDic = Dictionary(grouping: res, by: { $0.customer})
DispatchQueue.main.async {
self.tableView.reloadData()
}
override func numberOfSections(in tableView: UITableView) -> Int {
return portfoliosDic.keys.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let keys = Array(portfoliosDic.keys)
let item = portfoliosDic[keys[section]]!
return item.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cellId")
let keys = Array(portfoliosDic.keys)
let arr = portfoliosDic[keys[indexPath.section]]!
let customer = arr[indexPath.row]
//cell.textLabel?.text = customer.serial
let titleStr = [customer.serial, customer.manufacturer, customer.model].compactMap { $0 }.joined(separator: " - ")
print(titleStr)
// Get references to labels of cell
cell.textLabel!.text = titleStr
return cell
}
Upvotes: 1