I want to ask how to implement the files as sections depends on userId
then show all again in the tableview.
I'm started build simple project I fetched JSON file as decoder and show all in table view:
func fetchUsers(using url: String){
let url = URL(string: url)!
let _ = URLSession.shared.dataTask(with: url){ (data,response,error)
in
guard let data = data else {return}
do{
let objects = try JSONDecoder().decode([User].self, from: data) // decode * ( Codable )
self.users = objects
} catch{
print("error loading data cause: \(error)")
}
}.resume()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "users",for: indexPath) as? customeCellTableViewCell{
let indexRow = users[indexPath.row]
cell.dataModel(forModel: indexRow)
return cell
}
return UITableViewCell()
}
private func numberOfUsers(in users: [User]) -> Int {
return 1
}
func numberOfSections(in tableView: UITableView) -> Int {
return numberOfUsers(in: self.users)
}
Like @vadian mentions tuples should be avoided for this so here is an improved solution.
Instead of a tuple we can use a struct to hold the grouped data
struct UsersByID {
let id: Int
var users : [User]
}
then change the load
function to
func load(withUsers users: [User]) {
let dict = Dictionary(grouping: users) { return $0.userID }
usersByID = dict.map { (key, values) in
return UsersByID(id: key, users: values)
}.sorted(by: { $0.id < $1.id })
}
The rest of the code is the same but replace key
with id
and value
with users
Old solution
First create a dictionary to hold your sections (keys) and rows (values) as a property in the view controller
var usersByID = [(key: Int, value: [User])]()
then fill that dictionary using grouping:by:
using the array from json
func load(withUsers users: [User]) {
usersByID = Dictionary(grouping: users, by: { user in
user.userID }).sorted(by: { $0.0 < $1.0})
}
then the table view functions use this dictionary
override func numberOfSections(in tableView: UITableView) -> Int {
return usersByID.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return usersByID[section].value.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return String(usersByID[section].key)
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "LabelCell", for: indexPath)
let user = usersByID[indexPath.section].value[indexPath.row]
cell.textLabel?.text = user.title
//...
return cell
}