Objective c 此HealthKit错误的原因是什么;将样本添加到训练时出错";?

Objective c 此HealthKit错误的原因是什么;将样本添加到训练时出错";?,objective-c,ios8,healthkit,Objective C,Ios8,Healthkit,我明白为什么,但HealthKit所提出的错误的模糊性完全是一个黑匣子。为什么会出现错误: 将样本添加到训练时出错:操作无法完成 我一直在网上搜寻例子,但大多数都是用swift( 这是我的密码: - (NSSet *)dataTypesToRead { HKQuantityType *heartRate = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate]; return [

我明白为什么,但HealthKit所提出的错误的模糊性完全是一个黑匣子。为什么会出现错误:

将样本添加到训练时出错:操作无法完成

我一直在网上搜寻例子,但大多数都是用swift(

这是我的密码:

- (NSSet *)dataTypesToRead {
    HKQuantityType *heartRate = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate];

    return [NSSet setWithObjects:heartRate, nil];
}

- (NSSet *)dataTypesToWrite {
    HKWorkoutType* workout = [HKWorkoutType workoutType];
    HKQuantityType *energyBurnedType = [HKQuantityType  quantityTypeForIdentifier:HKQuantityTypeIdentifierActiveEnergyBurned];

    return [NSSet setWithObjects:workout, energyBurnedType, nil];
}

- (void)saveWorkout {

    HKHealthStore* healthStore = [[HKHealthStore alloc] init];

    NSDate* timeOfWorkout = [NSDate date];

    HKWorkoutType* type = [HKWorkoutType workoutType];

    [healthStore requestAuthorizationToShareTypes:[self dataTypesToWrite]
                                        readTypes:[self dataTypesToRead]
                                       completion:^(BOOL success, NSError *error) {

       if(success == YES)
       {
           // This sample uses hard-coded values and performs all the operations inline
           // for simplicity's sake. A real-world app would calculate these values
           // from sensor data and break the operation up using helper methods.

           HKQuantity *energyBurned =
           [HKQuantity quantityWithUnit:[HKUnit kilocalorieUnit]
                            doubleValue:333.0];

           HKQuantity *distance =
           [HKQuantity quantityWithUnit:[HKUnit mileUnit]
                            doubleValue:0.0];

           // Provide summary information when creating the workout.
           HKWorkout *workout = [HKWorkout workoutWithActivityType:HKWorkoutActivityTypeTraditionalStrengthTraining
                                                         startDate:timeOfWorkout
                                                           endDate:timeOfWorkout
                                                          duration:0
                                                 totalEnergyBurned:energyBurned
                                                     totalDistance:distance
                                                          metadata:nil];

           // Save the workout before adding detailed samples.
           [healthStore saveObject:workout withCompletion:^(BOOL success, NSError *error) {
               if (!success) {
                   // Perform proper error handling here...
                   NSLog(@"*** An error occurred while saving the "
                         @"workout: %@ ***", error.localizedDescription);

                   abort();
               }

           }];

           // Add optional, detailed information for each time interval
           NSMutableArray *samples = [NSMutableArray array];

           HKQuantityType *energyBurnedType =
           [HKObjectType quantityTypeForIdentifier:
            HKQuantityTypeIdentifierActiveEnergyBurned];


           [samples addObject:energyBurnedType];

           // Add all the samples to the workout.
           [healthStore
            addSamples:samples
            toWorkout:workout
            completion:^(BOOL success, NSError *error) {
                if (!success) {
                    // Perform proper error handling here...
                    NSLog(@"*** An error occurred while adding a "
                          @"sample to the workout: %@ ***",
                          error.localizedDescription);

                    abort();
                }
            }];
       }
       else
       {
           // Determine if it was an error or if the
           // user just canceld the authorization request
       }

   }];
}
这里我发现了两个问题

  • 在将训练保存到HealthKit之前,您正在尝试向训练添加样本
  • 样本数组应包含HKQuantitySample或HKCategorySample类型的对象
  • 这很好用

    - (NSSet *)dataTypesToRead {
        HKQuantityType *heartRate = [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierHeartRate];
    
        return [NSSet setWithObjects:heartRate, nil];
    }
    
    - (NSSet *)dataTypesToWrite {
        HKWorkoutType* workout = [HKWorkoutType workoutType];
        HKQuantityType *energyBurnedType = [HKQuantityType  quantityTypeForIdentifier:HKQuantityTypeIdentifierActiveEnergyBurned];
    
        return [NSSet setWithObjects:workout, energyBurnedType, nil];
    }
    
    - (void)saveWorkout {
    
        HKHealthStore* healthStore = [[HKHealthStore alloc] init];
    
        NSDate* timeOfWorkout = [NSDate date];
    
        [healthStore requestAuthorizationToShareTypes:[self dataTypesToWrite]
                                            readTypes:[self dataTypesToRead]
                                           completion:^(BOOL success, NSError *error) {
    
                                               if(success == YES)
                                               {
                                                   // This sample uses hard-coded values and performs all the operations inline
                                                   // for simplicity's sake. A real-world app would calculate these values
                                                   // from sensor data and break the operation up using helper methods.
    
                                                   HKQuantity *energyBurned =
                                                   [HKQuantity quantityWithUnit:[HKUnit kilocalorieUnit]
                                                                    doubleValue:333.0];
    
                                                   HKQuantity *distance =
                                                   [HKQuantity quantityWithUnit:[HKUnit mileUnit]
                                                                    doubleValue:0.0];
    
                                                   // Provide summary information when creating the workout.
                                                   HKWorkout *workout = [HKWorkout workoutWithActivityType:HKWorkoutActivityTypeTraditionalStrengthTraining
                                                                                                 startDate:timeOfWorkout
                                                                                                   endDate:timeOfWorkout
                                                                                                  duration:0
                                                                                         totalEnergyBurned:energyBurned
                                                                                             totalDistance:distance
                                                                                                  metadata:nil];
    
                                                   // Save the workout before adding detailed samples.
                                                   [healthStore saveObject:workout withCompletion:^(BOOL success, NSError *error) {
                                                       if (!success) {
                                                           // Perform proper error handling here...
                                                           NSLog(@"*** An error occurred while saving the "
                                                                 @"workout: %@ ***", error.localizedDescription);
    
    //                                                       abort();
                                                       }
                                                       else
                                                       {
                                                           // Add optional, detailed information for each time interval
                                                           NSMutableArray *samples = [NSMutableArray array];
    
                                                           HKQuantityType *energyBurnedType =
                                                           [HKObjectType quantityTypeForIdentifier:
                                                            HKQuantityTypeIdentifierActiveEnergyBurned];
    
                                                           HKQuantity *energyBurnedQuantity = [HKQuantity quantityWithUnit:[HKUnit kilocalorieUnit] doubleValue:334];
    
                                                           HKQuantitySample *energyBurnedSample = [HKQuantitySample quantitySampleWithType:energyBurnedType quantity:energyBurnedQuantity startDate:[NSDate date] endDate:[NSDate date]];
    
                                                           [samples addObject:energyBurnedSample];
    
                                                           // Add all the samples to the workout.
                                                           [healthStore
                                                            addSamples:samples
                                                            toWorkout:workout
                                                            completion:^(BOOL success, NSError *error) {
                                                                if (!success) {
                                                                    // Perform proper error handling here...
                                                                    NSLog(@"*** An error occurred while adding a "
                                                                          @"sample to the workout: %@ ***",
                                                                          error.localizedDescription);
    
                                                                    //                                                        abort();
                                                                }
                                                            }];
    
                                                       }
    
                                                   }];
    
                                               }
                                               else
                                               {
                                                   // Determine if it was an error or if the
                                                   // user just canceld the authorization request
                                               }
    
                                           }];
    }
    

    控制台或设备上的崩溃日志中是否有任何消息?当您收到“操作无法完成”时Cocoa API中的错误,它通常表示与负责执行操作的系统守护进程通信时发生某种故障。例如,在这种情况下,healthd可能已崩溃。我收到的唯一控制台消息是:“***向训练添加样本时出错:操作无法完成。(Cocoa错误4097。)***"这很可能意味着healthd在响应您的请求时崩溃。您应该找到healthd崩溃日志,然后向Apple提交一个错误:。@tshortli,详细检查我的回答,确认崩溃是由于samples可变数组造成的。该数组包含一组HKQuantityType对象,但它应该是HKQuantitySample或HKCategorySample.T谢谢,我确实从一个样本中看到HealthKit中的“334”kcal,这正是我所需要的。一个问题,当使用workoutWithActivityType创建HKWorkout对象时,变量“energyBurned”是作为一个参数包含的,似乎没有使用。由于HKSample实际提供kcal,我可以将nil传递给此参数吗?如果不是,我如何处理此无关代码?@MattMiller,根据苹果的HealthKit设计理念,HKSample是HKQuantitySample和HKCategorySample类的基类。HKSample的目的是在我们的案例中,要存储样本的类型,它是“HKQuantityTypeIdentifierActivityBurned”。但是,HKSample不能存储数据的度量值(数量/类别)。存储此类数据是HKSample的子类的责任。即使无法通过“init”方法实例化HKSample。