【问题标题】:How to get walking and running distance using HealthKit in swift如何在 swift 中使用 HealthKit 获得步行和跑步距离
【发布时间】: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)
}

【问题讨论】:

    标签: swift healthkit hksamplequery


    【解决方案1】:

    如果您的代码将返回一个值

    1. 您已向用户请求读取权限 从 HealthKit 中的 distanceWalkingRunning
    2. 用户已授予您的应用权限。

    如果不是,您的代码将返回 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];
    

    }

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-05
    • 2017-02-19
    • 2021-09-13
    相关资源
    最近更新 更多