Reputation: 59
I currently have a problem that when I try to delete a row from a table, my app crashes and throws an index out of range error. The data deletes fine from the firebase database and the table, but it still throws the error.
The database is designed to store playlists, and each playlist has a dictionary of keys to the name of the song. Here is my firebase structure:
And below is the swift code (line where error is occurring has a comment)
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
let song = songs[indexPath.row]
var songKey = ""
if(editingStyle == .delete){
let ref = Database.database().reference().child("Playlists/\(playlist!)")
ref.observe(.value, with: {
snapshot in
let someData = snapshot.value! as! [String: String]
for data in someData {
if(data.value == song){
songKey = data.key
break
}
}
ref.child(songKey).removeValue()
self.songs.remove(at: indexPath.row) //error on this line
self.myTableView.deleteRows(at: [indexPath], with: .fade)
self.myTableView.reloadData()
})
}
}
Thanks for any help!
Upvotes: 0
Views: 129
Reputation: 4921
I think what you should do is take another approach - handle the delete operation within its completion handler. This way you will make sure your data will be consistent. Because what happens if there is an error on your Firebase call? You have to handle this case as well. So do something like this and see what happens:
ref.child(songKey).removeValue { [weak self] error, _ in
if let error = error {
print("There was an error: ", error)
return
}
self?.songs.remove(at: indexPath.row)
self?.tableView.reloadData()
}
What I think is happening here is that your code enters an infinite loop - you use observe on your playlists
then you delete. So observe
's completion handler is called again and delete
is called again. After you deleted the item at this index, the index cannot be found on your array anymore. So just get your playlists from the database without observing any further changes.
In this case try using observeSingleEvent
.
Upvotes: 1