Husain Alhamali
Husain Alhamali

Reputation: 823

TableView being loaded before fetching data

I working with an application that retrieves data from HealthKit and then store them in an array. What I'm trying to do is load my tableViewController with the data in that array. But unfortunately when I run the application the table appears empty.

To be more clear, I have a method that do coding to retrieve the list of required data, if fills an array (which declared at the top of the class) with these fetched data.

What I did is I called this function in the viewDidLoad function, and I printed out the array but it was empty, so I moved the call of the method to the function viewDidAppear and printed out the array. The array successfully filled with the data but I still have a problem with dynamically fill the rows with the data of this array. It still appears blank. The problem as I understood is that the table view is being loaded before the array is filled with data. I tried another solution by calling the method self.tableView.reloadData() but no luck with that.

Could anyone please give me any idea to solve this issue?

UPDATE:

Here is the viewDidLoad function:

override func viewDidLoad() {
    super.viewDidLoad()


    authorizeHealthKit()
    updateLastGlucoRecords()
    println("\(glucoReadings)")
    dispatch_async(dispatch_get_main_queue()) {
        self.tableView.reloadData()
    }

}

And this the viewDidAppear function:

override func viewDidAppear(animated: Bool) {
    updateLastGlucoRecords()
    println("Hereeeee2:   \(glucoReadings)")
    dispatch_async(dispatch_get_main_queue()) {
        self.tableView.reloadData()
    }
}

Here is where the table should dynamically be loaded by the data:

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell

    let df = NSDateFormatter()
    let tf = NSDateFormatter()

    df.dateFormat = "yyyy-MM-dd"
    tf.dateFormat = "hh:mm:ss"

    let readingDateTime = dates[indexPath.row]

    let dateTabel = cell.viewWithTag(100) as! UILabel!
    let timeLabel = cell.viewWithTag(101) as! UILabel!
    let readingLabel = cell.viewWithTag(102) as! UILabel!
    let indicator = cell.viewWithTag(103) as UIView!


    dateTabel.text = df.stringFromDate(readingDateTime)
    timeLabel.text = tf.stringFromDate(readingDateTime)


    let reading = readings[indexPath.row]

    let doubleReading = getRecordDouble(reading)
    readingLabel.text = reading
    let sCase = recordCase(doubleReading!)
    switch (sCase) {
    case "Very low": indicator.backgroundColor = UIColor.redColor()
    case "Too low": indicator.backgroundColor = UIColor.orangeColor()
    case "Normal": indicator.backgroundColor = UIColor.greenColor()
    case "Too high": indicator.backgroundColor = UIColor.yellowColor()
    case "Very High": indicator.backgroundColor = UIColor.orangeColor()
    case "Danger": indicator.backgroundColor = UIColor.redColor()
    default: indicator.backgroundColor = UIColor.grayColor()
    }

    return cell
}

And lastly here is the method that retrieves the data from HealthKit:

func updateLastGlucoRecords()
{
    // 1. Construct an HKSampleType for weight
    let sampleType = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBloodGlucose)
    // 2. Call the method to read the most recent weight sample
    self.healthManager.readRecent10GlucoseReadings(sampleType, completion: {(allReadings, error) -> Void in
        println()
        if (error != nil) {
            println("Error reading glucose readings from HealthKit Store: \(error.localizedDescription)")
            return;
        }

        var glucoseLocalizedString = self.kUnknownString;
        self.glucoses = allReadings as? [HKQuantitySample]
        for reading in self.glucoses! {

            if let record = reading.quantity {
                glucoseLocalizedString = "\(record)"
                let dateTimeRecorded = reading.startDate
                self.glucoReadings.append(glucoseLocalizedString)
                self.glucoDates.append(dateTimeRecorded)
                println("Reading: \(self.glucoReadings), Date: \(self.glucoDates)")
            }
            dispatch_async(dispatch_get_main_queue(), { () -> Void in

            })
        }
    })
}

Upvotes: 4

Views: 4252

Answers (2)

user3821934
user3821934

Reputation:

Presumably, the query you are using in HealthKit includes a completion handler. This handler is called when the query completes, and that is where you should call reloadData.

Since the HealthKit call is asynchronous, you cannot rely on the array being populated in viewWillAppear or viewDidLoad.

Upvotes: 2

Quentin Hayot
Quentin Hayot

Reputation: 7876

Try to call self.tableView.reloadData() in the main thread after your array is filled:

dispatch_async(dispatch_get_main_queue()) {
      self.tableView.reloadData()
    }

And don't forget to make sure that your datasource methods are correctly implemented.

Upvotes: 2

Related Questions