I am trying to make a simple "Contacts" app. Everything works fine but I could not find a way to write the piece of data from CoreData to the tableView by sorted alphabetically.
I want that the people save their phone numbers and their names in CoreData and after that, they will be added to the array as Person object. Also, I want to write the names to the tableView cell label. As you can understand, those names must be in alphabetic order.
I have created the app with MVC and created an empty array to keep users' phone numbers and names. The type of the array is Person.
//Like below.
// I hold the informations in this array.
var personList = [Person]()
//here is the cell format I am using in the app.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath) as! TableViewCell
let person = personList[indexPath.row]
cell.imageBackground.tintColor = cell.backgroundColors.randomElement()
cell.imageLabel.text = String(person.personFirstLetter.first!)
cell.nameLabel.text = person.personName
return cell
}
//this is how I get data from the user.
@objc func getData() {
personList.removeAll(keepingCapacity: false)
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "People")
fetchRequest.returnsObjectsAsFaults = false
do {
let results = try context.fetch(fetchRequest)
for result in results as! [NSManagedObject]{
if let name = result.value(forKey: "name") as? String{
if let phoneNumber = result.value(forKey: "number") as? String{
if let firstLetter = result.value(forKey: "letter") as? String{
personList.append(Person(personName: name, personNumber: phoneNumber, personFirstLetter: firstLetter))
}
}
}
}
} catch {
print(error.localizedDescription)
}
I don't actually know what to share here and how or where to adopt the alphabetic sorting.
Thanks for all. Cheers!
The most efficient way is to sort the records while fetching them. And use the real type in the request rather than unspecified NSFetchRequestResult
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let fetchRequest = NSFetchRequest<People>(entityName: "People")
fetchRequest.sortDescriptors = [NSSortDecriptor(key: "name", ascending: true)]
Further don't map the objects to another type, use the People
class, declare the datasource array
var personList = [People]()
and this is the entire code to fetch the data, only one line
do {
personList = try context.fetch(fetchRequest)
} catch {
print(error.localizedDescription)
}
The changes in cellForRow
are quite subtle.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath) as! TableViewCell
let person = personList[indexPath.row]
cell.imageBackground.tintColor = cell.backgroundColors.randomElement()
cell.imageLabel.text = String(person.letter.first!)
cell.nameLabel.text = person.name
return cell
}