Я стажер iOS Разработчик, поэтому есть некоторые вещи, которые я до сих пор не очень хорошо понимаю. Я создаю приложение «Контакты», в котором имена отображаются внутри разделов, как и в оригинальном, но с добавлением функции удаления.
У меня следующая проблема:
Если у меня есть контакт Один в разделе, как здесь Я удаляю его, проведя пальцем, и все в порядке. Но если я добавлю этот же контакт в приложение «Контакт» на устройстве, а затем go вернусь в мое приложение и потяну вниз, чтобы обновить sh, чтобы добавить обновление таблицы в мое приложение, я получу Фатальная ошибка: индекс выходит за пределы диапазона , приложение вылетает и застревает при загрузке индикатора активности.
Вот код:
Как я заполняю источник данных в своем классе менеджера
func addContactsToDictionary(from arrayOfContacts: [Contact]) {
for contact in arrayOfContacts {
let contactsKey = String(contact.firstName.prefix(1)) // Getting each given name's first letter
if var contactsValue = contactsDictionary[contactsKey] { // if there's already a value for the current key
contactsValue.append(contact) // Creating a value array of given names for the dictionary
contactsDictionary[contactsKey] = contactsValue // Adding a value array of given names to the current key in the dictionary
} else {
contactsDictionary[contactsKey] = [contact]
}
}
createAndSortSectionsArray()
}
func createAndSortSectionsArray() {
sectionTitles = [String](contactsDictionary.keys)
sectionTitles = sectionTitles.sorted(by: { $0 < $1})
}
Метод действия для элемента управления Refre sh, расположенного на контроллере табличного представления
@objc func handleRefresh() {
print("Attempting to refresh data")
let delay = 1
self.contactManager.contactsDictionary.removeAll() // To avoid duplicated data
self.contactManager.fetchContacts { (response, error) in
if let errorToCatch = error {
UITableViewController.Alert.showFetchingErrorAlert(on: self, message: errorToCatch.localizedDescription)
} else if let contactsArray = response {
self.contactManager.addContactsToDictionary(from: contactsArray)
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(delay)) {
self.tableView.reloadData()
self.myRefreshControl.endRefreshing()
}
}
Расширение контроллера табличного представления для источника данных
extension ContactsTableViewController {
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
let contactsInitialAsKey = contactManager.sectionTitles[indexPath.section]
if editingStyle == .delete {
contactManager.deleteContacts(at: indexPath)
contactManager.contactsDictionary[contactsInitialAsKey]!.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
if indexPath.row == 0 && contactManager.contactsDictionary[contactsInitialAsKey]!.isEmpty {
contactManager.contactsDictionary[contactsInitialAsKey] = nil
contactManager.sectionTitles.remove(at: indexPath.section)
tableView.reloadData()
}
}
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
contactManager.sectionTitles[section]
}
override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
return contactManager.sectionTitles
}
override func numberOfSections(in tableView: UITableView) -> Int {
return contactManager.sectionTitles.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let contactKey = contactManager.sectionTitles[section]
guard let contactValues = contactManager.contactsDictionary[contactKey] else { return 0 }
print(contactValues.map({ $0.firstName }), contactValues.count)
return contactValues.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ContactCell", for: indexPath) as! ContactCell
let contactKey = contactManager.sectionTitles[indexPath.section]
cell.contactsViewController = self
cell.setStarButton()
cell.setImageView()
if let contacts = contactManager.contactsDictionary[contactKey] {
print(contactKey, contacts.map { $0.firstName }, indexPath.section, indexPath.row)
cell.setDataToContactCell(contactData: contacts[indexPath.row]) // Where I get the Thread 1: Fatal error: Index out of range
}
return cell
}
}
До сих пор я мог только найти возможную проблему, выполнив следующие действия:
print (contactKey, contacts.map {$ 0.firstName}, indexPath.section, indexPath.row)
, чтобы увидеть, что происходит, и это то, что журнал показывает мне
Attempting to refresh data
Attempting to fetch contacts today...
Access granted
G ["Guga"] 2 1 //Here I noticed that for some reason the indexPath.row is not returning the correct value
Fatal error: Index out of range
2020-01-10 07:10:59.976537+0300 myContacts[12858:351184] Fatal error: Index out of range
Я посмотрел много похожих сообщений, но в большинстве из них Проблема с indexPath.row была связана с нажатием кнопки, чтобы получить ее. Поэтому я не нашел подходящего решения и не знаю, как решить эту проблему.
Буду очень признателен, если вы мне поможете. Спасибо!