FHIR® is the registered trademark of HL7 and is used with the permission of HL7. The Flame Design mark is the registered trademark of HL7 and is used with the permission of HL7.
Amsterdam, 15-17 November | @fhir_furore | #fhirdevdays17 | www.fhirdevdays.com
Easy FHIR Persistence with FireKit for iOS
Ryan Baldwin, eHealth Innovation @ University Health Network
About Me
• Name: Ryan Baldwin
• Background• Software Developer of 16 years
• Accidentally created • FireKit
• Restivus
• Author • Clojure Web Development Essentials
• Hates Shaving
Quick Assessment
• Who here knows FHIR?
• Who here knows Realm?
• Good news!• Familiarity is beneficial, but not required
• However, you should be familiar with • Swift
Agenda
• Origin Story
• What FireKit can do
• What FireKit cannot do
• How to Persist Your FHIR Data
• Serializing Your FHIR Data
• Working with a FHIR Server
Origin Story
Or How I Accidentally Find Myself in Amsterdam
What Is FireKit?
• A FHIR DSTU2 implementation in Swift• Full CRUD support with Realm
• Full Serialization to/from JSON• Swift 4 Codable compliant
• NSCopying compliant
• Realm CRUD helper functions
• Distributed under Apache 2 license
FireKit Limitations
• No API client… yet• BYOC: Bring Your Own Client
• Beholden to Realm’s “Rules of Engagement”• No implicit sharing of FHIR resources across thread
boundaries
• Writes must occur in a transaction
• No List of primitives
Creating a FHIR Resource
• Import FireKit; Import RealmSwift• FireKit contains the FHIR DSTU2
schema
• RealmSwift is the Realm Swift API
Creating a FHIR Resource
• Import FireKit; Import RealmSwift• FireKit contains the FHIR DSTU2
schema
• RealmSwift is the Realm Swift API
• Create a new Patient
Creating a FHIR Resource
• Import FireKit; Import RealmSwift• FireKit contains the FHIR DSTU2
schema
• RealmSwift is the Realm Swift API
• Create a new Patient
• Give that Patient a name!
Creating a FHIR Resource
• Import FireKit; Import RealmSwift• FireKit contains the FHIR DSTU2
schema
• RealmSwift is the Realm Swift API
• Create a new Patient
• Give that Patient a name!
• Finally, save that patient• FireKit provides the primary key
• String property called pk
Retrieving Realm Objects
• Realm provides query mechanics• objects<T>(_: T.Type) -> Results<T>
• filter
• Sorted
• object<T>(_: T.Type, forPrimaryKey) -> T?
• FireKit provides 2 extensions:• resources<T>(_: T.Type, withIds: [String]) -> Results<T>
• resource<T>(_: T.Type, withId: String) -> T?
Retrieving All Objects for a Type
• Use objects(_:) to retrieve a Results list of those objects
Retrieving All Objects for a Type
• Use objects(_:) to retrieve a Results list of those objects
Filter Results
• Use objects(_:) to retrieve a Results list of those objects
• Use filter(_:) to filter the results.
Sort Results
• Use objects(_:) to retrieve a Results list of those objects
• Use filter(_:) to filter the results.
• Use sorted(_:) to sort the results by field
See more filter options at https://academy.realm.io/posts/nspredicate-cheatsheet/
Get an Object by Primary Key
• object(ofType:, forPrimaryKey)• Returns the object, or nil
• Remember: Every FireKit object has a primary key
FireKit Extension: Getting Resources
• Query for type where id is in list
• This is a convenience function • Wraps around realm.objects and
filter
FireKit Extension: Getting Resources
• Query for type where id is in list
• This is a convenience function • Wraps around realm.objects and
filter
• Can also apply filter and sorted
FireKit Extension: Get Single Resource by id
• Get a single resource of a given type by it’s resource id
Managed vs. Unmanaged Realm Objects
• Unmanaged Objects are not in a Realm• New, unsaved objects
Managed vs. Unmanaged Realm Objects
• An object becomes managed when it’s persisted to a realm
Managed vs. Unmanaged Realm Objects
• An object becomes managed when it’s persisted to a realm
• Once managed, the object cannotbe modified outside a write transaction.
Managed vs. Unmanaged Realm Objects
• An object becomes managed when it’s persisted to a realm
• Once managed, the object cannotbe modified outside a write transaction.• Wrap the edit in a write block
• Alternatively, use beginWrite() and commitWrite()
Editing a Resource
• 4 ways to edit a FHIR Resource• Edit individual properties
• upsert a property
• Use copy/populate technique
• Bonus Jonus! realm.upsert<T>(:)
• All must be performed inside a write transaction
Editing a Resource – Individual Properties
• We’ve already seen this• Update individual properties in write
transaction
Editing a Resource – Individual Properties
• We’ve already seen this• Update individual properties in write
transaction
Editing a Resource – Upserting a property
• upsert(:)• To update or insert
• Create a template of what you want
• Blindly assign template property• Spouses will not share status
Editing a Resource – Copy/Populate
• copy()• provides unmanaged copy of the
source
• Does not duplicate primary keys
• populate(from:)• migrates values from source to
target
• Complete replacement; • does not perform intelligent merge
Editing a Resource – Bonus Jonus!
• What to do with downloaded Resources?• Update? Create a new one?
• Neither! You upsert it!• Logic based on the Resource’s id
• Will insert or update appropriately
Editing a Resource – Bonus Jonus!
• What to do with remote Resources?• Update? Create a new one?
• Neither! You upsert it!• Logic based on the Resource’s id
• Will insert or update appropriately
• Also handles arrays of Resources
Deleting a Resource
• Don’t use Realm’s realm.delete(:) on Resources or Elements• Does not cascade
• Risks orphans
• Use FireKit’s cascadeDelete()• Properly deletes
Resources/Elements
• No more orphans
JSON Serialization
• All FireKit classes conform to Swift 4’s Codable protocol
JSON Serialization
• All FireKit classes conform to Swift 4’s Codable protocol• Serialize using Swift 4’s JSONEncoder
JSON Serialization
• All FireKit classes conform to Swift 4’s Codable protocol• Serialize using Swift 4’s JSONEncoder
• Deserialize using Swift 4’s JSONDecoder
Integrating with a FHIR Server
• No API client in FireKit• Yet?
• Use Restivus as a simple alternativehttps://ryanbaldwin.github.io/Restivus
• Protocol-oriented
• Works around Swift 4’s Encodableand Decodable protocols
• Focus on structure, not on infrastructure
An Example Restivus Request
• Get the contents of the Google Home Page• Model the request
An Example Restivus Request
• Get the contents of the Google Home Page• Model the request
• Conform it to the proper Protocol• Gettable
• Postable
• Puttable
• Patchable
• Deletable
An Example Restivus Request
• Get the contents of the Google Home Page• Model the request
• Conform it to the proper Protocol• Gettable
• Postable
• Puttable
• Patchable
• Deletable
• What are we expecting back? Where are we fetching from?
An Example Restivus Request
• Get the contents of the Google Home Page• Model the request
• Conform it to the proper Protocol• Gettable
• Postable
• Puttable
• Patchable
• Deletable
• What are we expecting back? Where are we fetching from?
• Submit it!
Another Example – Download a Patient
• Create the request
Another Example – Download a Patient
• Create the request
• Conform the request to Gettable• We are expecting a Patient
• Use String interpolation to construct the path dynamically
Another Example – Download a Patient
• Create the request
• Conform the request to Gettable• We are expecting a Patient
• Use String interpolation to construct the path dynamically
• Submit it!
Last Example – Post a Patient
• Create the request
Last Example – Post a Patient
• Create the request
• Conform to Postable• Expect an OperationOutcome
Last Example – Post a Patient
• Create the request
• Conform to Postable• Expect an OperationOutcome
• Conform to Encodable• Populates the request body with
JSON
• Single Value Container for just the Patient JSON
Last Example – Post a Patient
• Create the request
• Conform to Postable• Expect an OperationOutcome
• Conform to Encodable• Populates the request body with
JSON
• Single Value Container for just the Patient JSON
• Submit it!
FireKit + Restivus = Easy Basic Client
• FireKit Codables
• Much more to Restivus than presented• Should be enough to get you started
Summary
• FireKit• Provides a Realm-ready FHIR DSTU2 spec
• Easily update and delete complex FHIR models in Realm
• Codable Conformant – Easily Serialize/Deserialze your data
• NSCopying Conformant – Easily copy your data
• Restivus• Easily create and submit Requests to a Server
• Automatically inflates ready-to-use responses from JSON
• Stays out of your way
That’s all she wrote!
FireKit:https://github.com/ryanbaldwin/FireKit
Restivus:https://ryanbaldwin.github.io/Restivus
Codable:http://apple.co/2AqcloLhttp://bit.ly/2znNuSn http://bit.ly/2yes7kU