Reputation: 310
My Tableview does not respond to any touches when it starts loading data from firebase. (It already shows the cells, but does not react) After a while it does the scrolling you tried to do when the tableview wasn't reacting.
var filteredData = [archivCellStruct]()
func firData() {
filteredData.removeAll()
var databaseRef : DatabaseReference!
databaseRef = Database.database().reference()
databaseRef.child("Aufträge").child("Archiv").queryOrderedByKey().observe(.childAdded, with:{
snapshot in
let snap = snapshot.value as? NSDictionary
//extracting the data and appending it to an Array
self.filteredData.append(//myData)
self.tableView.reloadData()
})
}
So it is working for smaller amounts of data (tableview rows) but with big delay(and I am already filtering the data to limit the data displayed in the tableView). I think it has something to do with the tableView.reloadData() (maybe userinteraction is disabled while reloading?)
Upvotes: 0
Views: 140
Reputation: 145
With the firebase you can go manual way:
UseCase:
struct UseCaseName {
struct Request {}
struct Response {
let firebaseCallbackData: [FirebaseModelType]
}
struct ViewModel {
let data: [DisplayType]
}
}
ViewController:
var filteredData: [DisplayType]! = []
override func viewWillAppear() {
// this one can make you trouble, adjust the observation logic to whatever you need. `WillAppear` can fire multiple times during the view lifecycle
super.viewWillAppear()
interractor?.observe()
}
func showData(viewModel: Scene.Usecase.ViewModel) {
// this is where the different approach begins
tableView.beginUpdates()
var indexPaths = [NSIndexPath]()
for row in (filteredData.count..<(FilteredData.count + viewModel.data.count)) {
indexPaths.append(NSIndexPath(forRow: row, inSection: 0))
}
filteredData += viewModel.data
tableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: .Automatic)
tableView.endUpdates()
}
Interractor:
func observe(request: Scene.UseCase.Request) { /* signup for updates with observe(_ eventType: DataEventType, with block: @escaping (DataSnapshot) -> Void) -> UInt */
callback is something like { DataSnapshot in presenter.presentData(response: Scene.Usecase.Response())
}
Presenter:
func presentData(response: Scene.UseCase.Response) {
/* format for representation */
DispatchQueue.main.async {
controller.present(viewModel: Scene.UseCase.ViewModel())
}
}
Sorry for the separation of the flow, I've got addicted to this way.
Also I'm assuming, that the data in the firebase is not modified, but added (because of observe(.childAdded,
part. If I'm wrong, please edit your question to reflect that. Another assumption is that you have the single section. Don't forget to change the inSection: 0
to the proper section. I'm to lazy and SO isn't that friendly for mobile devices
This way only appends new values sent by Firebase and works faster
EDIT: on another answer.
DispatchQueue.main.async { //change this in you code
self.tableView.reloadData()
}
Sometimes it's not good to reload all items. It depends on the count however. If my assumptions are correct, it'll be better to update separate cells without reloading the whole table on change. Quick example: something like a chat with the Firebase "backend". explanation: adding a single row will work faster then reloadData() anyway, but the difference is heavy only when you call those methods often. With the chat example, the difference may be huge enough in case the chat is spammy to optimize the UITableView reload behaviour in your controller.
Also it'll be nice to see the code, which affects the methods. It maybe a threading issue, like the John Ayers told in the comments. Where do you call func firData()
?
Upvotes: 1
Reputation:
everytime you have to reload your tableview asynchronously -
var filteredData = [archivCellStruct]()
func firData() {
filteredData.removeAll()
var databaseRef : DatabaseReference!
databaseRef = Database.database().reference()
databaseRef.child("Aufträge").child("Archiv").queryOrderedByKey().observe(.childAdded, with:{
snapshot in
let snap = snapshot.value as? NSDictionary
//extracting the data and appending it to an Array
self.filteredData.append(//myData)
DispatchQueue.main.async { //change this in you code
self.tableView.reloadData()
}
})
}
Upvotes: 1