FHIRModels is a Swift library for FHIR® resource data models.
- Native Swift representation of FHIR resources, elements and data types
- Separate targets for DSTU2, R4 and latest build versions
- Enforced non-nullability of mandatory parameters
- Enums for most closed code systems
- Enums to support value[x] types
- Date/Time parsing and validation
- Swift Codable support
FHIRModels works with Swift 5.0 and newer.
Swift Package Manager is the recommended way to add FHIRModels to your project:
- In Xcode 11, go to “File” » “Swift Package Management” » “Add Package Dependency...”
- Search for "FHIRModels" in the panel that comes up or paste the full URL to the GitHub repository, then select the package
- Pick the versioning that best works for you (usually the current version and "up to next major")
- In order to update the dependency, periodically select “Update to Latest Package Versions” from Xcode 11's “File” » “Swift Package Management” menu
Alternatively, you can add FHIRModels to your Package.swift
file as a dependency:
dependencies: [
.package(url: "https://github.com/apple/FHIRModels.git",
.upToNextMajor(from: "0.1.0"))
]
Assuming you have data that you know represents a FHIR resource, you have two options of instantiating a model. We'll assume you have JSON data for the examples below.
The ResourceProxy
type inspects the resourceType
in the data and instantiates the appropriate class for you:
import ModelsR4
let data = <FHIR JSON data>
let decoder = JSONDecoder()
do {
let proxy = try decoder.decode(ResourceProxy.self, from: data)
let resource = proxy.get()
// `resource` is a generic `Resource`
let patient = proxy.get(if: Patient.self)
// `patient` is a nullable `Patient`
if case .patient(let patient) = proxy {
// `patient` is a `Patient`
}
switch proxy {
case .patient(let patient):
// `patient` is a `Patient`
break
default:
break
}
} catch {
print("Failed to instantiate: \(error)")
}
If you think you know the correct resource type already:
import ModelsR4
let data = <FHIR JSON data>
let decoder = JSONDecoder()
do {
let resource = try decoder.decode(Patient.self, from: data)
} catch {
print("Failed to instantiate Patient: \(error)")
}
FHIR Resource and Element types are represented as Swift classes,
primitive data types are represented as structs.
All primitives are defined as FHIRPrimitive
,
genericized to the appropriate type such as FHIRBool
or DateTime
.
The library makes extensive use of ExpressibleBy{Type}Literal
so you can take shortcuts when instantiating primitives.
For example, HumanName.given
is an Array of FHIRPrimitive<FHIRString>
that can be instantiated as follows:
import ModelsR4
let name = HumanName(family: "Altick", given: ["Kelly"])
let patient = Patient(name: [name])
name.given?.first // FHIRPrimitive<FHIRString>?
name.given?.first?.value // FHIRString?
name.given?.first?.value?.string // String?
FHIRModels handles date/time ↔︎ string conversion transparently and will discard invalid dates.
do {
let dateTimeString = "2020-03-12T12:33:54.6543-06:00"
let dateTime = try DateTime(dateTimeString)
dateTime.date.year == 2020
dateTime.time.minute == 33
dateTime.timeZone == TimeZone(secondsFromGMT: -6 * 3600)
} catch {
print("Failed to parse date time string: \(error)")
}
Please feel free to open GitHub issues for questions, suggestions or issues you may have. Because the majority of the codebase is generated we will not be able to accept Pull Requests at this time.
This work is APACHE 2.0 licensed.
FHIR® is the registered trademark of HL7 and is used with the permission of HL7. Use of the FHIR trademark does not constitute endorsement of this product by HL7.