测试已测试 | ✓ |
语言语言 | SwiftSwift |
许可证 | Apache 2 |
发布最后发布 | 2016年3月 |
SPM支持SPM | ✗ |
由Eric Whitley维护。
依赖项 | |
GRMustache.swift | ~> 0.11.0 |
Fuzi | = 0.3.0 |
尝试 | ~> 1.0.0 |
CDAKit for iOS,一个开源的临床文档架构库,具有HealthKit连接功能。帮助您快速管理CDA结构化健康数据。
CDAKit提供C32和C-CDA的导入和导出功能,以及将CDA概念与HealthKit样本连接的能力。这允许在CDA和HealthKit之间桥接,以便您可以与电子病历系统集成。
CDAKit的模型、导入器和导出器基于RubyHealth-Data-Standards项目(HDS),该项目由美国国家协调员办公室的健康信息技术办公室(ONC)资助并由MITRE公司(MITRE)主要构建。
您可以在以下链接中了解更多关于CDAKit背后的某些理念:LinkedIn文章。
CDAKit不会存在,如果没有Ruby Health-Data-Standards库。特别是以下个人,他们的领导、承诺和辛勤工作有助于推动医疗保健互操作性
let doc = ((supply your CDA XML string))
do {
//let's try to import from CDA
let record = try CDAKRecord(fromXML: doc)
//let's create a new vital
// use the coded values to govern "meaning" (height, weight, BMI, BP items, etc.)
let aVital = CDAKVitalSign()
aVital.codes.addCodes("LOINC", code: "3141-9") //weight
aVital.values.append(CDAKPhysicalQuantityResultValue(scalar: 155.0, units: "lb"))
aVital.start_time = NSDate().timeIntervalSince1970
aVital.end_time = NSDate().timeIntervalSince1970
//append our height to our record
record.vital_signs.append(aVital)
//OK, let's convert our CDAK record to HealthKit
let hkRecord = CDAKHKRecord(fromCDAKRecord: record)
//let's explicitly set our preferred units to metric for a few things
CDAKHealthKitBridge.sharedInstance.CDAKHKQuantityTypeDefaultUnits[.HKQuantityTypeIdentifierHeight] = "cm"
CDAKHealthKitBridge.sharedInstance.CDAKHKQuantityTypeDefaultUnits[.HKQuantityTypeIdentifierBodyMass] = "kg"
//now let's convert back from HealthKit to our model
let cdakRecord = hkRecord.exportAsCDAKRecord()
//render from our model to CDA - format set to .ccda (could also do .c32)
print(cdakRecord.export(inFormat: .ccda))
}
catch {
//do something
}
CDAKit 自豪地使用以下项目
在您的应用程序中引用 CDAKit
import CDAKit
CDAKit 使用一个表示核心 CDA 文档的“Record”对象(CDAKRecord
)。在记录中包含单独的条目(CDAKEntry
),它们具有更精确的类型,用于元素如就诊、药物、过敏等。
CDAKRecord: 中央记录
CDAKEntry: 您详细 CDA 内容。这些可能是 CDAKEntry
或更具体的子类,如 CDAKAllergy
、CDAKMedication
、CDAKEncounter
等。
CDAKCodedEntries 和 CDAKCodedEntry: 这些代表医学术语系统和概念代码之间的配对(或配对集合)。
CDAKPhysicalQuantityResultValue: 一个计量单位(磅、英寸、毫米等)及其相关值(1、2.3、75等)的配对。
条目可以包含表示词汇编码的概念代码的 codes
。例如,“BMI”(体重指数)可以用 LOINC:39156-5(身体质量指数(BMI)[比率])表示。在没有编码数据的情况下,该概念对互操作性而言实际上是“无意义的”。虽然我们可以阅读文本描述“BMI”,但编码词汇条目对于机器理解信息片段的意图含义至关重要。
向条目添加编码数据
let aVital = CDAKVitalSign()
aVital.codes.addCodes("LOINC", code: "3141-9") //weight
词汇密钥是灵活的,但也有些固定密钥有助于确保有“首选”词汇的概念能够能够解决首选与翻译条目之间的选择。
通过 CDAKVocabularyKeys
可以获得已知常用密钥的列表。
然后,您可以像下面这样使用这些常量:
let aVital = CDAKVitalSign()
aVital.codes.addCodes(CDAKVocabularyKeys.LOINC, code: "3141-9") //weight
这可能是首选的方法,以确保一致性并确保相关 OID 查找成功。
您还可以提供一个可选的描述性 displayName
,它将出现在最终编码的结果中。
let aVital = CDAKVitalSign()
aVital.codes.addCodes(CDAKVocabularyKeys.LOINC, code: "3141-9", displayName: "Body Weight") //weight
从任何位置导入您的 CDA XML。如果您需要一些示例 CDA 文件,波士顿儿童医院已设置了一个优秀的存储库。
一旦您有了 XML,您可以通过解析 String
创建一个 CDAKRecord
。预期 XML 是一个格式良好的 XML 文档,其根元素为 ClinicalDocument
。
let myXML:String = ((Get some CDA XML))
do {
//try to import some CDA XML
let record = try CDAKRecord(fromXML: myXML)
}
catch {
}
CDA 解析特定错误可能有几种类型,都定义在 CDAKImportError
public enum CDAKImportError : ErrorType {
case NotImplemented
case UnableToDetermineFormat
case NoClinicalDocumentElement
case InvalidXML
}
ClinicalDocument
,但它不包含任何已知的模板 OIDs。ClinicalDocument
根元素。一旦您的 CDAKRecord 被填充,您就可以将其导出到支持的 CDA XML 格式之一。
格式如下所示:
let myOutboundCDAXML = cdakRecord.export(inFormat: .ccda)
print(myOutboundCDAXML)
CDAKit 使用 XML 文件 ClinicalDocument
标头中的 templateId
OIDs 确定格式(在 bulk_record_importer
中找到)。
默认情况下,无法检测任何这些 OIDs 将导致文档解析异常。某些文档模板可能包含有效的 CDA,但不会使用这些 OIDs。它们可能只使用“US General Realm”标头。
您可以在尝试导入之前指定全局 CDAKit 单例中的 attemptNonStandardCDAImport
标志来尝试找到任何“可能支持”的文件。
CDAKGlobals.sharedInstance.attemptNonStandardCDAImport = true
然后,您可以尝试导入未指定的 CDA 文件。
CDAKGlobals.sharedInstance.attemptNonStandardCDAImport = true //enable wider support
let myCDAXMLWithoutTheRightType:String = ((Get some non-standard CDA XML))
do {
//try to import some CDA XML
let record = try CDAKRecord(fromXML: myCDAXMLWithoutTheRightType:String)
}
catch {
}
您可以在 CDA 模型和 HealthKit 模型之间进行转换,以建立两种不同表示之间的关系。有关方法的详细讨论,请参阅此处。
此过程使用一个中间的 CDAKHKRecord
模型来存储 HealthKit 样本。如果您有现有的 HealthKit 样本,只需将它们添加到 samples
集合中。理想情况下,您还能提供一些基本的名字和性别信息。
您可能会遇到两个挑战
HealthKit 桥为这两个问题都提供了默认行为,但您几乎肯定会希望根据您的具体需求对其进行修改。
将从CDA导入到HealthKit可以迅速完成,方法是转换CDA导向的CDAKRecord为与HealthKit兼容的记录。为此,您只需从CDA的CDAKRecord
初始化一个(HealthKit) CDAKHKRecord
。
let doc = ((my CDA XML))
do {
//try to import some CDA XML
let record = try CDAKRecord(fromXML: doc)
//OK, let's convert our CDAK record to HealthKit
let hkRecord = CDAKHKRecord(fromCDAKRecord: record)
for sample in hkRecord.samples {
print(sample)//these are all HKQuantitySamples
}
}
catch {
}
您可以使用exportAsCDAKRecord
方法快速将一个HealthKit CDAKHKRecord
转换为CDA导向的CDAKHKRecord
。该方法会读取HealthKit桥接记录中的所有samples
并尝试将临床概念和相关单位表示转换为CDA结构。
//our wrapping record for HealthKit stuff
let hkRecord = CDAKHKRecord()
//Let's create a HealthKit height
let aUnit = HKUnit(fromString: "in")
let aQty = HKQuantity(unit: aUnit, doubleValue: 72 )
let aQtyType = HKQuantityType.quantityTypeForIdentifier(HKQuantityTypeIdentifierHeight)
let hkHeight = HKQuantitySample(type: aQtyType!, quantity: aQty, startDate: NSDate(), endDate: NSDate())
//store the sample in our record
hkRecord.samples.append(hkHeight)
//convert the HealthKit record to CDAKRecord
let cdakRecord = hkRecord.exportAsCDAKRecord()
HealthKit桥接默认输出单位为通过首选项文件管理的设置。
如果您希望为给定的一组数量类型设置默认单位,可以按HealthKit样本类型标识符进行。
CDAKHealthKitBridge.sharedInstance.CDAKHKQuantityTypeDefaultUnits[.HKQuantityTypeIdentifierHeight] = "cm"
您可以通过更改CDAKHKQuantityTypeDefaultUnits
修改大量默认单位,这是在运行时存储单位映射的字典。
示例
["HKQuantityTypeIdentifierBasalBodyTemperature", "degF"]
这最初是从CDAKit中的本地CDAKitDefaultSampleTypeIdentifierSettings
资源文件中加载的。
该plist使用unit
键及其关联的string
值。
<key>HKQuantityTypeIdentifierBasalBodyTemperature</key>
<dict>
<key>unit</key>
<string>degF</string>
如果您想导出HealthKit对象,可能希望让用户的个人单位设置驱动HKUnit选择(如果可能的话)。例如,我们可能将“体重温度”以华氏度导入,但用户可能希望看到以摄氏度呈现的信息。如果他们的个人数量类型的单位设置被设置,这将覆盖全局默认设置。
此功能使用HKHealthStore。假设所有授权都将由您的应用程序管理。
此功能修改了HealthKit样本 - NOT存储在CDAKRecord中的原生CDA数据。您必须在导出HKRecord(exportAsCDAKRecord)之前设置单位偏好。一旦导出到CDAKRecord,任何更改桥接的单位类型将不会被反映。CDA单位类型是固定字符串。
HealthKit在后台线程上做这个,所以在处理UI时请小心。
//create an instance of the HealthKit management service
let healthKitStore:HKHealthStore = HKHealthStore()
//NOTE: you'd need to handle authorizations for your specific sample types
//attempt to set the HealthKit bridge's desired target units to whatever the user's device preferences might be
CDAKHealthKitBridge.sharedInstance.setCDAKUnitTypesWithUserSettings(self.healthManager.healthKitStore)
这是HealthKit和CDA之间映射中最复杂和“个人偏好”的方面。例如,当您将HealthKit葡萄糖HKQuantityTypeIdentifierBloodGlucose
样本导出到CDA时,您希望使用哪个临床词汇表和概念代码?哪个测量单位最为合适?同样,当从CDA导入到HealthKit时,您如何推断“LOINC:2345-7”是一个血糖测量值?以及如何将基于CDA的多种UCUM单位转换为Apple期望的“mg/dl”?
CDAKit提供了两个关键机制来帮助:
HKQuantityTypeIdentifierBloodGlucose
asserting一个特定的词汇表类型和编码值集合cdaStringUnitFinder
闭包变量可以被开发人员使用以更改此行为以适应他们的特定需求。词汇映射尝试将HealthKit数量样本类型标识符与一组已知的词汇类型和相关代码关联起来。
在CDA中,你可能会收到以下编码条目XML格式的检验结果
<code
codeSystem="2.16.840.1.113883.6.1"
codeSystemName="LOINC"
code="2345-7"
displayName="Glucose, Serum" />
我们如何将其转换成HKQuantityTypeIdentifierBloodGlucose
呢?
我们简单地提供了一个从“LOINC:2345-7”到HKQuantityTypeIdentifierBloodGlucose
的映射。
CDAKit提供了两个映射来帮助处理这个问题
import
:仅在从CDA导入值到HealthKit时使用export
:仅在从HealthKit导出值到CDA时使用CDAKit提供了默认的精选“启动”映射,但你可以通过loadHealthKitTermMap
方法覆盖所有值。此方法接受基于以下结构定义的Swift字典[String:AnyObject]
code
、displayName
和映射限制的详细说明。code
是与displayName
(如:“体质指数(BMI)(比率)”)相关的词汇概念代码(如:39156-5)。 <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>
默认单位映射是一个原型,非常脆弱。它仅仅使用正则表达式和“最佳猜测”的组合来尝试将一组类似UCUM的单元字符串转换成HealthKit可以使用的格式。
如果开发者有他们希望处理的已知CDA结构,建议他们覆盖默认的单位匹配算法。
要做到这一点,只需通过cdaStringUnitFinder
变量提供自己的自定义闭包。
public var cdaStringUnitFinder : ((unit_string: String?, typeIdentifier: String? ) -> HKUnit?)?
这个模拟示例会简单地查找任何类似“跳动”的东西,并将其转换成HealthKit兼容的“/min计数”。
var cdaStringUnitFinder : ((unit_string: String?, typeIdentifier: String? ) -> HKUnit?) = {
(unit_string: String?, typeIdentifier: String?) -> HKUnit? in
if unit_string == "beats" {
return HKUnit(fromString: "count/min")
}
return nil
}
//Tell CDAKit to use your custom unit finder
CDAKHealthKitBridge.sharedInstance.cdaStringUnitFinder = cdaStringUnitFinder
CDAKit的记录导入过程创建的HKQuantitySample将包括一些自定义元数据键。这些旨在帮助您识别和管理基于CDA的样本(合并、删除等)。
public enum CDAKHKMetadataKeys: String {
case CDAKMetadataRecordIDRoot
case CDAKMetadataEntryHash
}
您还可以提供自己的Swift [String:AnyObject]字典以添加更多自定义元数据。
这项工作受Apache 2协议许可。