I am populating my CollectionView with loadData() which is called in the ViewDidLoad() method. In here, I parse all data from my Firebase realtime database to an array (posts). Then, in the cellForItemAt method, I set all images, labels and textviews accordingly based on the information in the posts array using indexPath.item. Pretty basic stuff.
However, I have two tables in my database: posts and users. In posts, I only collect the information regarding the post and the userID of the author. I then want to fetch the data from users, since the profile picture and username can change over time, so I don't want to make it sticky inside the posts table in the database.
The problem I had before: I loaded the data from the posts inside loadData() and then would get the user information in the cellForItemAt method based on the userID saved in the posts array. This caused my app to be choppy: scrolling to new cells initiated the cellForItemAt method, causing it to request the data, then updating it. So there would be a delay as the information had to be downloaded. Absolutely sure this was the cause, as I now set it to a default image (no profile picture image) and default username ("Username"), making it very smooth again.
I then moved on to fetch the userData and parse it to another array (userInfo):
struct userData {
var userFirstName: String
var userLastName: String
var userProfilePicURL: String
}
var userInfo = [String : userData]()
I can use this as userInfo[posts.userID], which is precisely what I was looking for. The issue I have now is that the userInfo is not populated in time, returning nil when I dump the array in cellForItemAt:
dump(userInfo[post.userID])
So this returns nil on loading the app, but when I scroll, and thus initialize cellForItemAt again, it does return values. So my educated guess would be that the data is not fetched in time. I am now looking for a way to only call cellForItemAt when the posts array ánd the user array is loaded.
How I add values to the user array, inside the loadData function, where dict["userID"] is obtained through observing the posts in the database:
Ref.child("users").child(dict["userID"] as! String).observeSingleEvent(of: .value) { (snapshot) in
let userValues = snapshot.value as! [String: Any]
userInfo[dict["userID"] as! String] = userData(userFirstName: userValues["userFirstName"] as! String, userLastName: userValues["userLastName"] as! String, userProfilePicURL: userValues["userProfilePicURL"] as! String)
}
I want to make sure that the information is added to the array before showing the cells, so they can change the profile picture and the username accordingly. I want to do this in the cellForItemAt method. I thought about using timers, hiding my CollectionView for a couple of seconds, but this would all depend on the connection speed etc. so I think there should be a more suitable solution.
Any useful ideas are welcome!