Reputation: 705
I am trying a statistical query for Heart Rate data in HealthKit.
The below code compiles but results in the following error upon function call:
fatal error: unexpectedly found nil while unwrapping an Optional value
The error occurs on this line:
let quantity : HKQuantity = result!.averageQuantity()!;
Why is result returning nil? I have verified that Heart Rate data is available in HealthKit so I don't believe it's because the data in the query does not exist.
Any Ideas? Is there a better way to do this?
Code below:
func readHeartRate() {
let sampleType = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)!
let nowDate = NSDate()
let calendar = NSCalendar.autoupdatingCurrentCalendar()
let yearMonthDay: NSCalendarUnit = [NSCalendarUnit.Year, NSCalendarUnit.Month, NSCalendarUnit.Day]
let components: NSDateComponents = calendar.components(yearMonthDay , fromDate: nowDate)
let beginOfDay : NSDate = calendar.dateFromComponents(components)!
let predicate : NSPredicate = HKQuery.predicateForSamplesWithStartDate(beginOfDay, endDate: nowDate, options: HKQueryOptions.StrictStartDate)
let squery = HKStatisticsQuery(quantityType: sampleType, quantitySamplePredicate: predicate, options: HKStatisticsOptions.None, completionHandler: { (squery, result, error) -> Void in
dispatch_async( dispatch_get_main_queue(), { () -> Void in
let quantity : HKQuantity = result!.averageQuantity()!;
let beats : Double = quantity.doubleValueForUnit(self.heartRateUnit)
print(beats)
})
})
healthKitStore.executeQuery(squery)
}
Upvotes: 3
Views: 596
Reputation: 705
I ended up taking a different approach here and was able to solve the problem by manually by querying for a set of Heart Rate data and taking the average.
Note: getDayofWeek function just takes an NSDate and returns a string for the day of week.
func readHRbyDate(latestXSamples: Int, startDate: NSDate, endDate: NSDate, completion: (((String, CGFloat), NSError!) -> Void)!)
{
let sampleType = HKObjectType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeartRate)
let predicate = HKQuery.predicateForSamplesWithStartDate(startDate, endDate: endDate, options: HKQueryOptions.None)
let sortDescriptor = NSSortDescriptor(key: HKSampleSortIdentifierStartDate, ascending: true)
var HRdata:(String,CGFloat) = ("N/A",0)
var bpm: Int = 0
var totalBPMforDay = [Int]()
var BPMCount: Int = 0
var sumBPM: Int = 0
let query = HKSampleQuery(sampleType: sampleType!, predicate: predicate, limit: latestXSamples, sortDescriptors: [sortDescriptor])
{ (query, results, error) in
if let queryError = error {
print("Problem fetching HR data")
completion(("nil",0.0),queryError)
return
}else{
for result in results! {
bpm = Int(((result.valueForKeyPath("_quantity._value"))?.floatValue)! * 60.0)
totalBPMforDay += [Int(((result.valueForKeyPath("_quantity._value"))?.floatValue)! * 60.0)]
BPMCount = Int(totalBPMforDay.count)
sumBPM += Int(((result.valueForKeyPath("_quantity._value"))?.floatValue)! * 60.0)
let HRAvg = sumBPM / BPMCount
HRdata = (self.getDayOfWeek(result.startDate),CGFloat(HRAvg))
}
if completion != nil {
completion(HRdata,nil)
}
}
}
healthKitStore.executeQuery(query)
}
Upvotes: 0
Reputation: 7353
The result
parameter is not guaranteed to be non-nil. You should only unwrap and use result if it is not nil, and otherwise examine error
to see what went wrong. There are a number of errors that you could expect to occur that are outside of your control (for instance the device could become locked while processing your query or the system daemon performing the query could crash).
Upvotes: 1