I am using CloudKit to store a few arrays, then use the arrays to fill a table. I am reloading the table, but it will not show any data. It should be connected to iCloud because I am still able to add to the database.
Code is shown below:
import UIKit
import CloudKit
var selectedCellName = ""
class explore: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var tableView: UITableView!
var groupNames = [String]()
var Group = [CKRecord]()
override func viewDidLoad() {
super.viewDidLoad()
loadGroups()
self.tableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return groupNames.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCell(withIdentifier: "exploreCell")! as UITableViewCell
// let nameCell = leaderboardInfo[indexPath.row].object(forKey: "Name") as! String
// let usernameCell = leaderboardInfo[indexPath.row].object(forKey: "Username") as! String
//let pointsCell = leaderboardInfo[indexPath.row].object(forKey: "Points") as! String
var nameCellLbl = cell.viewWithTag(100) as! UILabel
nameCellLbl.text = groupNames[indexPath.row]
return cell
}
}
Here is the loadGroups()
function which is used to query the database:
func loadGroups(){
print("should go")
// let pred = NSPredicate(format: "Username = %@", usernameText)
let pred = NSPredicate(value: true)
let query = CKQuery(recordType: "Group", predicate: pred)
let operation = CKQueryOperation(query: query)
//operation.resultsLimit = CKQueryOperationMaximumResults
operation.qualityOfService = .default
operation.recordFetchedBlock = { (record: CKRecord!) in
if record != nil{
// need self in front?
groupNames.append(record.object(forKey: "groupName") as! String)
//self.tableView.reloadData()
//print(self.groupNames.count)
}
}
database.add(operation)
//self.tableView.reloadData()
// print(leaderboardInfo.count)
}
This used to work, and if I made changes I made them months ago so I can't remember. Anyway this is the problem in all of my files where I query the database, but the table won't load it.
You're reloading the table view long before you actually query the data.
Remove the call to
reloadData
inviewDidLoad
.In
loadGroups
you need to setup a query completion handler. You need to deal with the possibility that the query completion hander will indicate that there is more data to load.You should build a new array from the queried data. Don't update
groupNames
until you have all of the data. Then, on the main queue, updategroupNames
with the queried results and then reload the table view.An even better solution is to add a completion handler to your
loadGroups
method. Then instead ofloadGroups
directly updatinggroupNames
and reloading the table view, it simply passes back a new array with all of the query data. Then the caller can update thegroupNames
and reload the table view it the completion block it passes to the call toloadGroups
.Then this can be called from your view controller as:
The above is a rough outline. This is not meant to be production ready.