Reputation: 4519
I have made this function to get all steps for each day but I want to convert this function from swift 2.x to swift 3. But I get stuck on 2 different points.
let anchorDate = calendar.dateComponents(anchorComponents)
I get this error: Cannot invoke dateCompontents with an argument of list type (Datecomponents)
And on this point:
let stepsQuery = HKStatisticsCollectionQuery(quantityType: HKQuantityType, quantitySamplePredicate: nil, options: .CumulativeSum, anchorDate: anchorComponents!, intervalComponents: interval)
Error: Cannot convert value of type HKQuantityType.Type to expected argument type HKQuantityType.
The complete function:
func getDailySteps(){
let calendar = NSCalendar.current
let interval = NSDateComponents()
interval.day = 1
var anchorComponents = calendar.dateComponents([.day , .month , .year], from: NSDate() as Date)
anchorComponents.hour = 0
let anchorDate = calendar.dateComponents(anchorComponents)
// Define 1-day intervals starting from 0:00
let stepsQuery = HKStatisticsCollectionQuery(quantityType: HKQuantityType, quantitySamplePredicate: nil, options: .CumulativeSum, anchorDate: anchorComponents!, intervalComponents: interval)
// Set the results handler
stepsQuery.initialResultsHandler = {query, results, error in
let endDate = NSDate()
let startDate = calendar.dateByAddingUnit(.Day, value: -7, toDate: endDate, options: [])
if let myResults = results{ myResults.enumerateStatisticsFromDate(startDate!, toDate: endDate) { statistics, stop in
if let quantity = statistics.sumQuantity(){
let date = statistics.startDate
let steps = quantity.doubleValueForUnit(HKUnit.countUnit())
print("\(date): steps = \(steps)")
//NOTE: If you are going to update the UI do it in the main thread
dispatch_async(dispatch_get_main_queue()){
//update UI components
}
}
} //end block
} //end if let
}
HKHealthStore?.executeQuery(stepsQuery)
}
So how can I convert this method to swift 3 ?
Upvotes: 2
Views: 1808
Reputation: 187
.dateComponents was removed as part of better translating Objective-C APIs into swift: https://github.com/apple/swift-evolution/blob/master/proposals/0005-objective-c-name-translation.md
Try
calendar.date(from: DateComponents)
As far as your healthkit issues, I suspect you need something more along the lines of
HKQuantityType.quantityType(forIdentifier: HKQuantityTypeIdentifier.stepCount
Rather than the entire HKQuantityType class.
Upvotes: 0
Reputation: 6092
Your code contains some more errors than you describe. I copied your code into a playground tried to fix it. I can't guarantee that it will work (I have never worked with HealthKit before, but it should at least compile.
In Swift 3, some classes have been renamed. For example NSCalendar
to Calendar
. The first two lines within your function have to be changed to this:
let calendar = Calendar.current
var interval = DateComponents()
To get a date from date components, you have to use this function:
calendar.date(from: anchorComponents)
After reading the documentation about HKStatisticsCollectionQuery and HKQuantityType I came up with this line of code:
let stepsQuery = HKStatisticsCollectionQuery(quantityType: HKQuantityType.quantityType(forIdentifier: .activeEnergyBurned)!, quantitySamplePredicate: nil, options: .cumulativeSum, anchorDate: anchorDate!, intervalComponents: interval)
HKQuantityType.quantityType(forIdentifier: .activeEnergyBurned)
replaces the HKQuantityType
in your old code.
anchorDate:
receives a Date
instead of DateComponents
.
And the enum-case you pass to options:
starts with a lowercase letter in Swift 3.
dateByAddingUnit
has been changed. In Swift 3, you use this:
calendar.date(byAdding: .day, value: -7, to: endDate)
(Again, the enum-case now starts with a lowercase letter.)
enumerateStatistics
has been changed, too. It's now:
enumerateStatistics(from: startDate!, to: endDate)
HKUnit.countUnit()
has been renamed:
let steps = quantity.doubleValue(for: HKUnit.count())
The way to use multiple threads has been changed massively.
DispatchQueue.main.async {
//update UI components
}
HKHealthStore?.executeQuery(stepsQuery)
is a bit strange. execute(_:)
(as it is named in Swift 3) is not static and can only be used on instances of HKHealthStore
. I fixed the error-message with the following line, but I'm not sure, if this will really work.
HKHealthStore().execute(stepsQuery)
*Additional errors I have found in your code when using it in a Playground.
Upvotes: 8