Reputation: 41
I'm making Health App. I want to get walkingRunningDistance
from HealthKit
in Swift. But, I have a problem. Return value is 0.0mile.
Why return value is 0 mile?
My code is this.
func recentSteps3(completion: (Double, NSError?) -> () ){
let type = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierDistanceWalkingRunning)
let date = NSDate()
let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let newDate = cal.startOfDayForDate(date)
let predicate = HKQuery.predicateForSamplesWithStartDate(newDate, endDate: NSDate(), options: HKQueryOptions.StrictStartDate)
let query = HKSampleQuery(sampleType: type!, predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: nil) { query, results, error in
var distance: Double = 0
if results?.count > 0
{
for result in results as! [HKQuantitySample]
{
distance += result.quantity.doubleValueForUnit(HKUnit.mileUnit())
}
}
completion(distance, error)
}
healthAuth.healthStore.executeQuery(query)
}
Upvotes: 4
Views: 11743
Reputation: 1
if it return zero then your code is correct. but since it is in simulator view, simulator you cannot read Distance. for that go to Health App in your simulator and select Distance Walking Running Distance and press add data
and then your app might read those data.
Upvotes: 0
Reputation: 122
After enabled the HealthKit in your project's capabilities and added the necessary "Privacy - Health Share Usage Description" key to your info.plist file...
Ensure you are requesting for the approval of the user by adding this to the ViewController.swift, practically in the viewDidLoad() function.
let store = HKHealthStore()
let stepType = HKQuantityType.quantityType(forIdentifier: .stepCount)!
let woType = HKObjectType.workoutType()
store.requestAuthorization(toShare: [], read: [stepType, woType], completion: { (isSuccess, error) in
if isSuccess {
print("Working")
self.getSteps()
} else {
print("Not working")
}
})
Then create the getSteps() function.
func getSteps() {
let startDate = Calendar.current.date(bySettingHour: 0, minute: 0, second: 0, of: Date())!
let endDate = Date()
print("Collecting workouts between \(startDate) and \(endDate)")
let predicate = HKQuery.predicateForSamples(withStart: startDate, end: endDate, options: HKQueryOptions.strictEndDate)
let query = HKSampleQuery(sampleType: HKQuantityType.quantityType(forIdentifier: .distanceWalkingRunning)!, predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: nil) { (query, results, error) in
for item in results! {
print(item)
}
}
store.execute(query)
}
Upvotes: 3
Reputation: 2873
Your code will return a value if
- You have requested permission from the user to read distanceWalkingRunning from HealthKit
- The user has granted your app permission.
If not, your code will return 0.
To request authorization, you can call
func requestAuthorization(toShare typesToShare: Set<HKSampleType>?, read typesToRead: Set<HKObjectType>?, completion: @escaping (Bool, Error?) -> Swift.Void)
where typesToRead
contains
let distanceType = HKSampleType.quantityType(forIdentifier: HKQuantityTypeIdentifier.distanceWalkingRunning)!
I believe that using a HKStatisticsQuery or HKStatisticsCollectionQuery will be more efficient. Here is an example.
guard let type = HKSampleType.quantityType(forIdentifier: .distanceWalkingRunning) else {
fatalError("Something went wrong retriebing quantity type distanceWalkingRunning")
}
let date = Date()
let cal = Calendar(identifier: Calendar.Identifier.gregorian)
let newDate = cal.startOfDay(for: date)
let predicate = HKQuery.predicateForSamples(withStart: newDate, end: Date(), options: .strictStartDate)
let query = HKStatisticsQuery(quantityType: type, quantitySamplePredicate: predicate, options: [.cumulativeSum]) { (query, statistics, error) in
var value: Double = 0
if error != nil {
print("something went wrong")
} else if let quantity = statistics?.sumQuantity() {
value = quantity.doubleValue(for: HKUnit.mile())
}
DispatchQueue.main.async {
completion(value)
}
}
healthStore.execute(query)
Upvotes: 7
Reputation: 84
healthStore =[HKHealthStore new];
HKQuantityType *stepType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
HKSampleType *sleepType = [HKSampleType categoryTypeForIdentifier:HKCategoryTypeIdentifierSleepAnalysis];
HKQuantityType *walkType = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierDistanceWalkingRunning];
NSArray *arrayType = @[stepType,sleepType,walkType];
[healthStore requestAuthorizationToShareTypes:[NSSet setWithArray:arrayType]
readTypes:[NSSet setWithArray:arrayType] completion:^(BOOL succeeded, NSError *error) {
if (succeeded) {
NSLog(@"Not working");
NSLog(@"error %@",error);
} else {
NSLog(@"Working!");
NSLog(@"error %@",error);
}
[self getStepCount];
}];
The above method for requsting access and below method to get count
-(void)getStepCount{
NSInteger limit = 0;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd hh:mm:ss"];
NSDate *startDate = [NSDate dateWithTimeIntervalSince1970:1372418789];
// Divided by 1000 (i.e. removed three trailing zeros) ^^^^^^^^
NSString *formattedDateString = [dateFormatter stringFromDate:startDate];
// Fri, 28 Jun 2013 11:26:29 GMT
NSLog(@"start Date: %@", formattedDateString);
NSDateFormatter *dateFormatter1=[[NSDateFormatter alloc] init];
[dateFormatter1 setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSLog(@"%@",[dateFormatter1 stringFromDate:[NSDate date]]);
NSString *dateString =[dateFormatter1 stringFromDate:[NSDate date]];
NSDate *endDate = [dateFormatter1 dateFromString:dateString];
NSPredicate *predicate = [HKQuery predicateForSamplesWithStartDate:startDate endDate:endDate options:HKQueryOptionStrictEndDate];
HKSampleQuery *query = [[HKSampleQuery alloc] initWithSampleType:[HKObjectType quantityTypeForIdentifier:HKQuantityTypeIdentifierDistanceWalkingRunning]
predicate: predicate
limit: limit
sortDescriptors: nil
resultsHandler:^(HKSampleQuery *query, NSArray* results, NSError *error){
dispatch_async(dispatch_get_main_queue(), ^{
// sends the data using HTTP
int dailyAVG = 0;
NSLog(@"result : %@",results);
for(HKQuantitySample *samples in results)
{
NSLog(@"dailyAVG : %@",samples);
}
NSLog(@"dailyAVG : %d",dailyAVG);
NSLog(@"%@",@"Done");
});
}];
[healthStore executeQuery:query];
}
Upvotes: 0