CDAKHealthKitBridge
public class CDAKHealthKitBridge
Provides HealthKit bridging with CDA structures.
You can create HealthKit samples and convert them to CDA or take CDA objects and convert them to HealthKit samples.
Right now HealthKit exposes samples for things that are like
some vitals and laboratory results. These can be inferred by reviewing the associated CDA vocabulary code entries and the individual result values.
NOTE: some common HealthKit samples do not yet universally accepted vocabulary concepts. These includes concepts HKQuantityTypeIdentifierStepCount
, which do not yet have LOINC (or SNOMED CT) codes.
We have provided default curated mappings for some codes. These can be found in the CDAKitDefaultHealthKitTermMap
plist file.
Possible future Concepts and codes:
Fitness Identifiers
LOINC has begun to track some of this, but it’s in trial
mode
There is also a more generalized Exercise tracking panel
that includes distances and durations
-
Singleton for all shared properties and methods.
Declaration
Swift
public static let sharedInstance = CDAKHealthKitBridge()
-
Placeholder for non-localized HealthKit quantity identifier descriptions.
Example: [
HKQuantityTypeIdentifierBasalBodyTemperature
,Basal Body Temperature
]This is initially loaded from the local
CDAKitDefaultSampleTypeIdentifierSettings
resource file in CDAKit.The plist uses the
displayName
key and associatedstring
value<key>HKQuantityTypeIdentifierBasalBodyTemperature</key> <dict> <key>displayName</key> <string>Basal Body Temperature</string>
Declaration
Swift
public var CDAKHKQuantityTypeDescriptions: [String:String] = [:]
-
Default preferred units for a given set of quantity types.
Example: [
HKQuantityTypeIdentifierBasalBodyTemperature
,degF
]This is initially loaded from the local
CDAKitDefaultSampleTypeIdentifierSettings
resource file in CDAKit.The plist uses the
unit
key and associatedstring
value<key>HKQuantityTypeIdentifierBasalBodyTemperature</key> <dict> <key>unit</key> <string>degF</string>
You can, instead, use the individual user’s preferred unit settings from their Health App settings. If you wish to do so, use the
setCDAKUnitTypesWithUserSettings
methodDeclaration
Swift
public var CDAKHKQuantityTypeDefaultUnits: [CDAKHKQuantityIdentifiers:String] = [:]
-
Default classification for a specified quantity type identifier.
Two primary groups as of version 1.0:
- vital
- result
These attempt to tie the HealthKit concepts to a given CDA section for convenience (vitals or lab results).
Example: [
HKQuantityTypeIdentifierBasalBodyTemperature
,vital
]This is initially loaded from the local
CDAKitDefaultSampleTypeIdentifierSettings
resource file in CDAKit.The plist uses the
type
key and associatedstring
value<key>HKQuantityTypeIdentifierBasalBodyTemperature</key> <dict> <key>type</key> <string>vital</string>
Declaration
Swift
public var CDAKHKQuantityTypeDefaultTypes: [String:String] = [:]
-
Convenience enumeration of all HealthKit quantity identifiers
See moreDeclaration
Swift
public enum CDAKHKQuantityIdentifiers: String
-
For a given HealthKit biologicalSex, returns a tuple of the CDA code and displayName.
Reference: https://www.hl7.org/fhir/v3/AdministrativeGender/index.html
Example CDA element:
<administrativeGenderCode code="M" codeSystem="2.16.840.1.113883.5.1" codeSystemName="AdministrativeGenderCode" displayName="Male"/>
Declaration
Swift
public func administrativeGender(biologicalSex:HKBiologicalSex?)-> (code:String, displayName:String)
Parameters
biologicalSex
HKBiologicalSex
Return Value
tuple of the CDA code and displayName EX: (
F
, “Female) -
For a given CDA HL7 gender code, returns an HKBiologicalSex.
Reference: https://www.hl7.org/fhir/v3/AdministrativeGender/index.html
Example CDA element:
<administrativeGenderCode code="M" codeSystem="2.16.840.1.113883.5.1" codeSystemName="AdministrativeGenderCode" displayName="Male"/>
Declaration
Swift
*/ public func administrativeGender(genderCode:String?)-> HKBiologicalSex
Parameters
genderCode
(String) HL7 gender code
Return Value
HKBiologicalSex if match found for HL7 code
-
Attempts to converts a CDA entry to a HealthKit quantity sample.
This method relies completely on both the concept and unit mapping functions.
Concepts are matched/found based on coded entries bound to HealthKit sample identifier types. These can be found in the
CDAKitDefaultHealthKitTermMap
plist file. You can inject your own input/output concept mappings through theloadHealthKitTermMap
method.Units are matched based on a function that reviews units against known formats. If you wish to change it (you probably will), you can do so by supplying your own closure. Just update
cdaStringUnitFinder
and all unit matching logic will be changed at runtime.Declaration
Swift
public func sampleForEntry(entry: CDAKEntry, forSampleType sampleType: CDAKHKQuantityIdentifiers? = nil, withHKMetadata meta: [String:AnyObject] = [:]) -> HKQuantitySample?
Parameters
entry
CDAKEntry - the CDA entry you wish to convert to a HealthKit sample.
forSampleType
Optional (ENUM) CDAKHKQuantityIdentifiers - The type of HealthKit sample you’d like to create. If you do not specify a sample type, the function will attempt to choose a compatible sample type for you
withHKMetadata
[String:AnyObject] - Custom metadata you may wish to apply to HealthKit samples
-
Closure that allows you to specify how unit strings from CDA templates are transformed into HealthKit units (if possible)
Refer to unitForCDAString for information on arguments
var cdaStringUnitFinder : ((unit_string: String?, typeIdentifier: String? ) -> HKUnit?) = { (unit_string: String?, typeIdentifier: String?) -> HKUnit? in //example if unit_string == "beats" || aTypeIdentifier == HKQuantityTypeIdentifierBodyMassIndex { return HKUnit(fromString: "count/min") } return nil }
Declaration
Swift
public var cdaStringUnitFinder : ((unit_string: String?, typeIdentifier: String? ) -> HKUnit?)?
-
There are a fixed number of HKUnit code strings we can use to initialize an HKUnit. EX:
cm
dL
etc. CDA does not, however, entirely fix that list like HKUnit. We’ve seen inches units which should be represented byin
be formatted with unit strings likeinch
orinches.
Additionally, the UCUM units CDA uses may be somewhat broader than HKUnit SI units. EX: inch may be represented as
in_us
There may also be formatting conventions in CDA that make it difficult to utilize the identifier strings with HealthKit. EX:
[in_us]
orhh[Mg]
We need to attend to all of these scenarios to see if we can
clean up
the CDA unit codes so they’re viable for HKUnit’s fromString initializer.Declaration
Swift
public func unitForCDAString(var unit_string: String?, forQuantityTypeIdentifier typeIdentifier: String? = nil) -> HKUnit?
Parameters
unit
_string: The CDA unit identifier you are attempting to use to create an HKUnit.
forQuantityTypeIdentifier
The HK Quantity Type identifier you are trying to tie to the unit. There are certain quantity types (BMI) that use units like
count
which would be in direct conflict with the typical units likekg/m^2
used by many medical record systems. The quantity type is then used to completely override the unit codes and force them (for better or for worse) to conform to HealhtKit’s preferred unit.Return Value
Optional HKUnit. If one can be created, it will be populated.
-
If you want to export HealthKit objects, you may want to let the user’s personal unit settings drive the HKUnit selection (where possible). For example, we may import a
body temperature
in Fahrenheit, but a user may prefer to see that information rendered in Celsius. If their personal unit settings for a quantity type are set, this will overwrite the global defaults with the user’s preferred setting.This feature uses HKHealthStore. It is assumed all authorizations will be managed by your application.
NOTE: This functionality modifies the HealthKit samples - NOT the native CDA data stored in the CDAKRecord. You must set the unit preferences BEFORE you export a HKRecord (exportAsCDAKRecord). Once exported to a CDAKRecord, any changes to the bridge’s unit types will not be reflected. CDA unit types are fixed strings.
NOTE: HealthKit does this on a background thread, so be careful how you handle things on the UI
Version
iOS 8.2 and above
Declaration
Swift
public func setCDAKUnitTypesWithUserSettings(store: HKHealthStore)
Parameters
store
HKHealthStore that that will allow access to preferredUnitsForQuantityTypes
-
Allows you to specify the type of unit that should be preferred for a particular HealthKit quantity type identifier
Declaration
Swift
public func setPreferedUnitForSampleType(preferredUnitString unit: String, forHKQuantityTypeIdentifier type: String)
Parameters
preferredUnitString
unit string (EX:
cm
)forHKQuantityTypeIdentifier
the type identifier
-
Supplies a list of all supported HealthKit quantity types
Declaration
Swift
public var supportedHKQuantityTypes: Set<HKQuantityType>
-
Supplies a list of all supported HealthKit sample type identiifers
Declaration
Swift
public var supportedHKQuantityTypeIdentifiers: Set<String>
-
Allows you to tell the sample generator how it should classify a specificy type of sample and what it should use for default units (works in tandem with the unit match closure).
- The primary key is HealthKit sample type identifier you wish to bind. (EX:
HKQuantityTypeIdentifierActiveEnergyBurned
) unit
is the default unit (EX:cal
)displayName
is the display name you wish to use for the sample (EX:Active Energy Burned
)type
defines how you want to classify the sample. These attempt to tie the HealthKit concepts to a given CDA section for convenience (vitals or lab results).
Two primary
type
groups as of version 1.0:- vital
- result
<key>HKQuantityTypeIdentifierActiveEnergyBurned</key> <dict> <key>unit</key> <string>cal</string> <key>displayName</key> <string>Active Energy Burned</string> <key>type</key> <string>vital</string> </dict>
Declaration
Swift
*/ public func loadHealthKitQuantityTypeMetadata(withPlist plist: NSDictionary)
- The primary key is HealthKit sample type identifier you wish to bind. (EX:
-
Allows you to inject your own HealthKit sample type mappings to CDA vocabulary entries. These mappings are the core of what drives the linkage between the two.
The mappings must specify a direction:
import
: used exclusively when importing values from CDA to HealthKitexport
: used exclusively when exporting values from HealthKit to CDAboth
: used for import and exportThe primary key is HealthKit sample type identifier you wish to bind.
Within this, there is a child array bound to the key/tag CDAKit uses to map to a vocabulary. EX:
LOINC
orSNOMED-CT
. This declares that all following coded entries within the array will be of that specified vocabulary.Details for
code
,displayName
, and mapping restriction.code
is the vocabulary concept code (EX: 39156-5) for the associateddisplayName
(EX:Body mass index (BMI) [Ratio]
).
<key>HKQuantityTypeIdentifierBodyMassIndex</key> <dict> <key>LOINC</key> <array> <dict> <key>code</key> <string>39156-5</string> <key>displayName</key> <string>Body mass index (BMI) [Ratio]</string> <key>mapRestriction</key> <string>both</string> </dict> </array> ... (more vocabularies) </dict>
Declaration
Swift
public func loadHealthKitTermMap(withPlist plist: NSDictionary)