Robbie Wilson
Robbie Wilson

Reputation: 37

How to get data from CloudKit before loading TableData

I'm writing an app in Swift where the first scene has a TableView, I have it setup to display the title and it works fine, I also have it setup to count occurrences in a CloudKit database(or whatever its called) but it performs the count in async so the table defaults to show 0 in the detail pane.

I need to know how to make the app wait before it sets the value for the right detail until the count is completed or how to change them afterwards.

I have attached the code I used to perform the count etc, if I am doing this wrong or inefficiently please let me know

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationItem.hidesBackButton = true;

    self.textArray.addObject("Link 300")
    self.textArray.addObject("Link 410")
    self.textArray.addObject("Link 510")

    let container = CKContainer.defaultContainer()
    let publicData = container.publicCloudDatabase

    let query = CKQuery(recordType: "Inventory", predicate: NSPredicate(format: "TRUEPREDICATE", argumentArray: nil))

    publicData.performQuery(query, inZoneWithID: nil){results, error in
        if error == nil {
            for res in results {
                let record: CKRecord = res as! CKRecord

                if(record.objectForKey(("TrackerModel")) as! String == "Link 300"){
                    self.count300 = self.count300++
                }else if(record.objectForKey(("TrackerModel")) as! String == "Link 410"){
                    self.count410 = self.count410++
                }else if(record.objectForKey(("TrackerModel")) as! String == "Link 510"){
                    self.count510 = self.count510++
                }
            }
        }else{
            println(error)
        }
    }

    self.detailArray.addObject(self.count300.description)
    self.detailArray.addObject(self.count410.description)
    self.detailArray.addObject(self.count510.description)
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.textArray.count
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->UITableViewCell {
    var cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell
    cell.textLabel?.text = self.textArray.objectAtIndex(indexPath.row) as? String
    cell.detailTextLabel?.text = self.detailArray.objectAtIndex(indexPath.row) as? String
    return cell
}

Many thanks - Robbie

Upvotes: 0

Views: 479

Answers (1)

Paulw11
Paulw11

Reputation: 114783

The closure associated with the performQuery will complete asynchronously - that is after viewDidLoad has finished. You need to make sure that you reload your table view once the query has completed and you have the data. You also have a problem because you are updating your totals outside the closure - this code will also execute before the data has loaded.

Finally, make sure that any update to the UI (such as reloading the table view) is dispatched on the main queue

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationItem.hidesBackButton = true;

    self.textArray.addObject("Link 300")
    self.textArray.addObject("Link 410")
    self.textArray.addObject("Link 510")

    let container = CKContainer.defaultContainer()
    let publicData = container.publicCloudDatabase

    let query = CKQuery(recordType: "Inventory", predicate: NSPredicate(format: "TRUEPREDICATE", argumentArray: nil))

    publicData.performQuery(query, inZoneWithID: nil){results, error in
        if error == nil {
            for res in results {
                let record: CKRecord = res as! CKRecord

                if(record.objectForKey(("TrackerModel")) as! String == "Link 300"){
                    self.count300++
                }else if(record.objectForKey(("TrackerModel")) as! String == "Link 410"){
                    self.count410++ 
                }else if(record.objectForKey(("TrackerModel")) as! String == "Link 510"){
                    self.count510++
                }
            }
            self.detailArray.addObject(self.count300.description)
            self.detailArray.addObject(self.count410.description)
            self.detailArray.addObject(self.count510.description)
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                self.tableView.reloadData()
            })
        }else{
            println(error)
        }
    }
}

Upvotes: 1

Related Questions