如何在 swift 中使用 HealthKit 获得步行和跑步距离
Posted
技术标签:
【中文标题】如何在 swift 中使用 HealthKit 获得步行和跑步距离【英文标题】:How to get walking and running distance using HealthKit in swift 【发布时间】:2016-05-10 12:14:20 【问题描述】:我正在制作健康应用程序。我想在 Swift 中从 HealthKit
获取 walkingRunningDistance
。但是,我有一个问题。返回值为 0.0 英里。
为什么返回值为 0 英里?
我的代码是这样的。
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)
【问题讨论】:
【参考方案1】:如果您的代码将返回一个值
您已向用户请求读取权限 从 HealthKit 中的 distanceWalkingRunning 用户已授予您的应用权限。
如果不是,您的代码将返回 0。
要请求授权,您可以调用
func requestAuthorization(toShare typesToShare: Set<HKSampleType>?, read typesToRead: Set<HKObjectType>?, completion: @escaping (Bool, Error?) -> Swift.Void)
typesToRead
包含在哪里
let distanceType = HKSampleType.quantityType(forIdentifier: HKQuantityTypeIdentifier.distanceWalkingRunning)!
我相信使用 HKStatisticsQuery 或 HKStatisticsCollectionQuery 会更有效。这是一个例子。
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)
【讨论】:
我可以使用这种方法进行持续监控吗?用例:想要创建一个显示距离、速度、卡路里的应用程序,因为应用程序正在运行。试过这个,但数据正在以指数速度增加(样本数量)。计时器是周期性的,持续时间为 1 秒。【参考方案2】:对于 Swift 4.1
在您的项目功能中启用 HealthKit 并将必要的“隐私 - 健康共享使用说明”键添加到您的 info.plist 文件后...
确保您通过将其添加到 ViewController.swift 中来请求用户的批准,实际上是在 viewDidLoad() 函数中。
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")
)
然后创建 getSteps() 函数。
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)
【讨论】:
您请求的HKQuantityType
的授权与您以后尝试查询的不同,这不起作用,您必须拥有您查询的类型的授权,因此您需要更改stepType
之类的此let stepType = HKQuantityType.quantityType(forIdentifier: .distanceWalkingRunning)!
或查询应更改为stepCount
let query = HKSampleQuery(sampleType: HKQuantityType.quantityType(forIdentifier: .stepCount)!, predicate: predicate, limit: HKObjectQueryNoLimit, sortDescriptors: nil) ...
【参考方案3】:
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];
];
上面的请求访问方法和下面的方法获取计数
-(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];
【讨论】:
它在目标 c 中工作正常。请使用 objectivec2swift.com/#/converter 快速转换为 swift以上是关于如何在 swift 中使用 HealthKit 获得步行和跑步距离的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Swift 在 iOS 中显示从 HealthKit 中检索到的 HKDocumentSample?
如何在 swift 3 中获取和更新 Healthkit 中的高度?