简体   繁体   中英

Swift - Get glucose data from Apple HealthKit

I'm doing some tutorials about how to send and receive data to and from Apple HealthKit app.

Part of the tutorial I'm doing is how to get the height from the healthKitStore.

I want to do the same thing but to retrieve the glucose data instead of the height, I did all the steps but got stuck at this piece of code:

var heightLocalizedString = self.kUnknownString;
        self.height = mostRecentHeight as? HKQuantitySample;
        // 3. Format the height to display it on the screen
        if let meters = self.height?.quantity.doubleValueForUnit(HKUnit.meterUnit()) {
            let heightFormatter = NSLengthFormatter()
            heightFormatter.forPersonHeightUse = true;
            heightLocalizedString = heightFormatter.stringFromMeters(meters);
        }

As shown, the meters var is being assigned a double value from the meterUnit, and then creating a constant formatter to format the meters var and assign it to the pre-declared var (heightLocalizedString)

My question is, when I use this method for the glucose reading, I face a couple of issues, the first problem is I can't figure out what glucose units are available, the only one I get is

HKUnitMolarMassBloodGlucose

and when I use it an error appears says "'NSNumber' is not a subtype of 'HKUnit'" , it's clear from the error this parameter is not a subtype of the HKUnit class.

Another issue is, as shown in the previous code there is a formatter for the height (NSLengthFormatter()) , but I can't see a such formatter for the Glucose.

Actually I'm not sure if have to follow exactly the tutorial to get the Glucose data, but also I don't see another manner to do so.

Any ideas please?

Here is the code I'm using to retrieve the glucose data:

func updateGluco(){

    let sampleType = HKSampleType.quantityTypeForIdentifier(HKQuantityTypeIdentifierBloodGlucose)
    self.healthManager?.readMostRecentSample(sampleType, completion: {(mostRecentGluco, error) -> Void in

        if (error != nil){
            println("Error reading blood glucose from HealthKit store: \(error.localizedDescription)")
            return;
        }

        var glucoLocalizedString = self.kUnknownString;
        self.gluco = mostRecentGluco as? HKQuantitySample
        println("\(self.gluco?.quantity.doubleValueForUnit(HKUnit.moleUnitWithMolarMass(HKUnitMolarMassBloodGlucose)))")
        self.gluco?.quantity.doubleValueForUnit(HKUnit.moleUnitWithMolarMass(HKUnitMolarMassBloodGlucose))
        if let mmol = self.gluco?.quantity.doubleValueForUnit(HKUnit.moleUnitWithMolarMass(HKUnitMolarMassBloodGlucose)) {
            glucoLocalizedString = "\(mmol)"
        } else {
            println("error reading gluco data!")
        }
        dispatch_async(dispatch_get_main_queue(), {() -> Void in
        self.glucoLabel.text = glucoLocalizedString})
    })
}

The "mmol" variable returns a nil value.

I don't know if this relates to my problem, but I've just read an article said that Apple brought back blood glucose tracking in iOS 8.2 and my application deployment target is 8.1. (I can't upgrade the deployment target to the latest iOS despite that the XCode is updated to the last release!)

Looking in the header, blood glucose requires units of the type (Mass / Volume), which means you need to specify a compound unit with a Mass unit divided by a Volume unit:

HK_EXTERN NSString * const HKQuantityTypeIdentifierBloodGlucose NS_AVAILABLE_IOS(8_0);              // Mass/Volume,                 Discrete

Typically, the units that people measure blood glucose in are mg/dL, and mmol/L. You can construct these by using:

HKUnit *mgPerdL = [HKUnit unitFromString:@"mg/dL"];

HKUnit *mmolPerL = [[HKUnit moleUnitWithMetricPrefix:HKMetricPrefixMilli molarMass:HKUnitMolarMassBloodGlucose] unitDividedByUnit:[HKUnit literUnit]];

Note that doubleValueForUnit: requires an HKUnit, not an NSNumber. See for more information

I figured out the solution

To get the actual value of the sample gulco , I have only to use this property: self.gluco?.quantity , that's exactly what I wanted before.

The default unit for the Glucose in HealthKit is mg\\dL , in order to change the unit simply I extract the number value from the result and then divide it by 18.

Here is the code I'm using to retrieve the glucose data:

 NSInteger limit = 0;
    NSPredicate* predicate = [HKQuery predicateForSamplesWithStartDate:[NSDate date] endDate:[NSDate date] options:HKQueryOptionStrictStartDate];;
    NSString *endKey =  HKSampleSortIdentifierEndDate;
    NSSortDescriptor *endDate = [NSSortDescriptor sortDescriptorWithKey: endKey ascending: NO];
    HKSampleQuery *query = [[HKSampleQuery alloc] initWithSampleType: [HKQuantityType quantityTypeForIdentifier:HKQuantityTypeIdentifierBloodGlucose]
                                                           predicate: predicate
                                                               limit: limit
                                                     sortDescriptors: @[endDate]
                                                      resultsHandler:^(HKSampleQuery *query, NSArray* results, NSError *error)
                            {
                                dispatch_async(dispatch_get_main_queue(), ^{
                                    // sends the data using HTTP
                                    // Determine the Blood Glucose.
                                    NSLog(@"BloodGlucose=%@",results);

                                    if([results count]>0){
                                        NSMutableArray *arrBGL=[NSMutableArray new];
                                        for (HKQuantitySample *quantitySample in results) {
                                            HKQuantity *quantity = [quantitySample quantity];
                                            double bloodGlucosegmgPerdL = [quantity doubleValueForUnit:[HKUnit bloodGlucosegmgPerdLUnit]];
                                            NSLog(@"%@",[NSString stringWithFormat:@"%.f g",bloodGlucosegmgPerdL]);

                                        }
                                    }

                                });

                            }];

    [self.healthStore executeQuery:query];

// And Units :

@implementation HKUnit (HKManager)
+ (HKUnit *)heartBeatsPerMinuteUnit {
    return [[HKUnit countUnit] unitDividedByUnit:[HKUnit minuteUnit]];
}
+ (HKUnit *)bloodGlucosegmgPerdLUnit{
    return [[HKUnit gramUnit] unitDividedByUnit:[HKUnit literUnit]];
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM