How do I construct a HealthKit HKUnit for mmol/L (millimoles per liter) for Blood Glucose values?
Asked Answered
B

5

7

Blood glucose values were added back in Health in iOS 8.2: https://support.apple.com/en-us/HT203113

How do I construct a HealthKit HKUnit for mmol/L (millimoles per liter) for Blood Glucose values?

The following both throw exceptions: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse factorization string...

HKUnit *mmolPerL = [HKUnit unitFromString:@"mmol<molar mass>/L"];
HKUnit *mmolPerL = [HKUnit unitFromString:@"mmol/L"];
Beatty answered 11/5, 2015 at 21:11 Comment(0)
A
3

Can confirm that the examples provided don't work (every permutation), the alternative mg/dL unit does.

To sum up, both proposed approaches work, with similar (with the approach proposed by @cbartel the constant is actually rounded, not with the other) results regarding to the structure of the resulting HKUnit:

Printing description of mmolPerL->_baseUnits->_factors:
NSMapTable {
[6] mmol<180.15588> -> 1
[7] L -> -1
}

I'd use the shorter form using the provided constant:

HKUnit *mmolPerL = [HKUnit unitFromString:[NSString stringWithFormat:@"mmol<%f>/L",HKUnitMolarMassBloodGlucose]];
Antimony answered 11/5, 2015 at 21:48 Comment(1)
I couldn't get unitFromString: to work but I came up with a solution using unitDividedByUnit: See my answer above.Beatty
B
9

Construct two HKUnits and then perform unit math to create the complex unit:

HKUnit *mmolPerL = [[HKUnit moleUnitWithMetricPrefix:HKMetricPrefixMilli molarMass:HKUnitMolarMassBloodGlucose] unitDividedByUnit:[HKUnit literUnit]];
Beatty answered 12/5, 2015 at 16:31 Comment(1)
After reading @jrushing answer that looks like the way to go (using the provided constant btw)Antimony
T
8

In Swift 4:

let bloodGlucoseMgDlUnit = HKUnit.gramUnit(with: .milli).unitDivided(by: HKUnit.literUnit(with: .deci))
let bloodGlucoseMMolLUnit = HKUnit.moleUnit(with: .milli, molarMass: HKUnitMolarMassBloodGlucose).unitDivided(by: HKUnit.liter())

let mgdlValue = sample.quantity.doubleValue(for: bloodGlucoseMgDlUnit)
let mmollValue = sample.quantity.doubleValue(for: bloodGlucoseMMolLUnit)

Example:

81.0 mg/dL, 4.4961063718806 mmol/L
83.0 mg/dL, 4.6071213440258 mmol/L
Trillion answered 17/12, 2017 at 1:33 Comment(0)
S
4

Here's an example in Swift 4:

let mass = HKUnitMolarMassBloodGlucose
let mmolPerLiter = HKUnit.moleUnit(with: .milli, molarMass: mass).unitDivided(by: .liter())
Soubrette answered 27/8, 2017 at 18:5 Comment(0)
A
3

Can confirm that the examples provided don't work (every permutation), the alternative mg/dL unit does.

To sum up, both proposed approaches work, with similar (with the approach proposed by @cbartel the constant is actually rounded, not with the other) results regarding to the structure of the resulting HKUnit:

Printing description of mmolPerL->_baseUnits->_factors:
NSMapTable {
[6] mmol<180.15588> -> 1
[7] L -> -1
}

I'd use the shorter form using the provided constant:

HKUnit *mmolPerL = [HKUnit unitFromString:[NSString stringWithFormat:@"mmol<%f>/L",HKUnitMolarMassBloodGlucose]];
Antimony answered 11/5, 2015 at 21:48 Comment(1)
I couldn't get unitFromString: to work but I came up with a solution using unitDividedByUnit: See my answer above.Beatty
U
3

The "molar mass" passed to HKUnit's unitFromString: needs to be a decimal value representing the molar mass of the given substance.

Blood glucose has a molar mass of ~180.156 (see HKUnitMolarMassBloodGlucose in HKUnit.h for a more precise value). To construct this using unit strings you would want to use:

HKUnit *mmolPerL = [HKUnit unitFromString:@"mmol<180.156>/L"];
Unfold answered 13/5, 2015 at 4:9 Comment(1)
Saw the constant but the documentation was not that clear imho, this is the way to go.Antimony

© 2022 - 2024 — McMap. All rights reserved.