Skip to content

A healthy serialization library for your Apple HealthKit data.

License

Notifications You must be signed in to change notification settings

openmhealth/Granola

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Granola

A healthful serializer for your HealthKit data.

Overview

So you want to store your app's HealthKit data somewhere outside of HealthKit, perhaps a remote server for analysis or backup? Use Granola to serialize your data.

Granola spares you the effort of mapping HealthKit's API to JSON yourself, and emits JSON that validates against schemas developed by Open mHealth to ensure the data is intuitive and clinically meaningful.


Installation

CocoaPods

Granola is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "Granola"

Usage

Quick start

First, be sure to study Apple's HealthKit Framework Reference, which includes code samples illustrating how to ask your app's user for permission to access their HealthKit data, and how to query that data after you've gained permission.

Now, let's say you want to see what a "steps" sample data point looks like serialized to JSON.

// Granola includes OMHSerializer for serializing HealthKit data
#import "OMHSerializer.h"

// (initialize your HKHealthStore instance, request permissions with it)
// ...

// create a query for steps data
HKSampleType *stepsSampleType =
  [HKSampleType quantityTypeForIdentifier:HKQuantityTypeIdentifierStepCount];
HKSampleQuery* query =
  [[HKSampleQuery alloc] initWithSampleType:stepsSampleType
                                  predicate:nil
                                      limit:HKObjectQueryNoLimit
                            sortDescriptors:nil
                             resultsHandler:^(HKSampleQuery *query,
                                              NSArray *results,
                                              NSError *error) {
     if (!results) abort();
     // pick a sample to serialize
     HKQuantitySample *sample = [results first];
     // create and use a serializer instance
     OMHSerializer *serializer = [OMHSerializer new];
     NSString* jsonString = [serializer jsonForSample:sample error:nil];
     NSLog(@"sample json: %@", jsonString);
   }];
// run the query with your authorized HKHealthStore instance
[self.healthStore executeQuery:query];

Upon running your code, the console would render the data sample as Open mHealth compliant JSON:

{
  "body" : {
    "step_count" : 45,
    "effective_time_frame" : {
      "time_interval" : {
        "start_date_time" : "2015-05-12T18:58:06.969Z",
        "end_date_time" : "2015-05-12T18:58:32.524Z"
      }
    }
  },
  "header" : {
    "id" : "4A00E553-B01D-4757-ADD0-A4283BABAC6F",
    "creation_date_time" : "2015-05-12T18:58:06.969Z",
    "schema_id" : {
      "namespace" : "omh",
      "name" : "step-count",
      "version" : "1.0"
    }
  }
}

HKObjectType support

The serializer has support for all HealthKit samples (HKSample), either through curated Open mHealth schemas or through generic HealthKit schemas. The list of supported types along with their associated schemas is viewable here. The HKObjectType identifiers are pulled from the HealthKit Constant Reference.

You can retrieve a map (NSDictionary) of the supported types in Granola and the class name of the specific serializer they use by calling the static method:

[OMHHealthKitConstantsMapper allSupportedTypeIdentifiersToClasses]

You can also retrieve a list of those types, without their associated serializers, using the method:

[OMHSerializer supportedTypeIdentifiers]

And retrieve a list of types that serialize with Open mHealth curated schemas (instead of the generic type schemas) by using the method:

[OMHSerializer supportedTypeIdentifiersWithOMHSchema]

Over time, as curated schemas are developed that correspond to the HealthKit data represented by the generic schemas, the generic mappings will be replaced by mappings to the curated schemas.

Contact us to request support for a particular type or contribute support with a pull request.

Time zones

The serializer uses the time zone of the device to set the UTC offset in timestamps. For an iOS app using Granola, this means that serialized data contains timestamps with the UTC offset of the device running it. Although these timestamps are correct, some data, especially older data, that is being serialized may be offset incorrectly if it was originally created by HealthKit in a different time zone than the device is in when Granola serializes it. For example, if a data point was originally created by HealthKit in San Francisco on June 1st, 2015 at 8:00am (-07:00), but then serialized three months later in New York, the timestamp would read 2015-06-01T11:00-04:00. These are technically the same point in time, however they are offset differently.

In a future update, we plan to allow developers to specify the prefered time zone for serializing data points to give them control over how timestamps are serialized.

Contact

Have a question? Please open an issue!

Also, feel free to tweet at Open mHealth (@openmhealth).

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

License

Granola is available under the Apache 2 license. See the LICENSE file for more info.

Authors

Brent Hargrave (@brenthargrave)
Chris Schaefbauer (chris.schaefbauer@openmhealth.org)
Emerson Farrugia (emerson@openmhealth.org)