Reputation: 823
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
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
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