Exploring HealthKit With Xamarin: Provisioning and Permissions Illustrated Walkthrough

One of the more interesting frameworks in iOS 8 is Health Kit, system-wide persistent storage for health-related information. I’m just beginning to explore the namespace myself, but thought I’d walk through the steps you need to manipulate Health Kit with Xamarin.

Because health-related information is so sensitive, developing for Health Kit requires:

  1. The app be developed using an “Explicit App ID” with Health Kit Services explicitly enabled (see below);
  2. The Entitlements.plist must have a com.apple.developer.healthkit key set to true; and
  3. At initial runtime, the user must grant access via a detailed permissions dialog

Additionally, it’s worth emphasizing the importance of checking error codes in Health Kit API function calls. If a user does not grant permission or if for any other reason the app makes a call to a non-permitted API, this does not raise an exception. Rather, a null or otherwise empty result will be returned and typically an out NSError or closure-parameter will be set.

Provisioning and Permissions

Xamarin has a great article on device provisioning, but just to hit the highlights for Health Kit:

You need to set an “Explicit App ID” and explicitly enable “Health Kit” as an app service. Here, I’m created an ID for an app whose ID is “{PREFIX}.com.xamarin.HKWork”:

Screen-Shot-2014-07-11-at-7.49.46-AM

Screen Shot 2014-07-11 at 7.51.14 AM

After you do that, you’ll have to create a new provisioning profile for this App ID:

Screen Shot 2014-07-11 at 7.59.17 AM

Once you’ve awaited the generation of the profile, download it and double-click to install it on your development system:

Screen Shot 2014-07-11 at 8.05.17 AM

Now, in your Xamarin Studio project, open your Info.plist and set the Bundle Identifier to your explicit App ID (without the team prefix):

Screen Shot 2014-07-11 at 8.56.35 AM

And set your project’s Bundle Signing options so that you are using your new provisioning profile:

Screen Shot 2014-07-11 at 8.14.07 AM

(Now that I’ve written that, I suspect that you can probably leave it as “Automatic”, since the App ID is explicitly the same as that in the custom provisioning profile: that’s how the two are matched by the system. But still, I’m going to leave the step just to be clear what’s happening. And I don’t think there’s any harm in setting the provisioning profile explicitly.)

You’ve taken care of Info.plist, so now open Entitlements.plist. (Some project templates don’t automatically generate an Entitlements.plist file. If your project doesn’t have one, use File/New File…/iOS and choose Entitlements.plist.) Click on “Source” and add a new key com.apple.developer.HealthKit of type Boolean with a value of Yes (== true):

Screen Shot 2014-07-11 at 9.14.53 AM

Write code to request permission from the app user

To use Health Kit, the user must grant your app access. This involves these API calls:

var temperatureKey = HKQuantityTypeIdentifierKey.BodyTemperature;
var tempQuantityType = HKObjectType.GetQuantityType (temperatureKey);

var hks = new HKHealthStore ();
hks.RequestAuthorizationToShare (new NSSet (new [] { tempQuantityType }), new NSSet (), (success, error) => {
	Console.WriteLine ("Authorized:" + success);
	if (error != null) {
		Console.WriteLine ("Authorization error: " + error);
	}
});

Here, we are requesting authorization to share body temperature data (i.e., “share data generated by my app with the HealthStore database”). When this app is run, the user will be presented with the Health Kit permissions dialog, which will give the user fine-grained control over the requested types of data you’ll share. In this case, for instance, the dialog inside the Health app looks like this:

IMG_1314

Write a brilliant app

I have no insight into how to do that.

… that has some health-related information

Oh good, I can help with that.

Creating and storing data in the shared HealthKit store involves these API calls:

var temperatureKey = HKQuantityTypeIdentifierKey.BodyTemperature;
var tempQuantityType = HKObjectType.GetQuantityType (temperatureKey);
var myCurrentTemp = HKQuantity.FromQuantity (HKUnit.DegreeFahrenheit, 98.6);
var meta = NSDictionary.FromObjectAndKey (new NSNumber (4), HKMetadataKey.BodyTemperatureSensorLocation);
var tempSample = HKQuantitySample.FromType (tempQuantityType, myCurrentTemp, new NSDate (), new NSDate (), meta);

hks.SaveObject(tempSample, (success, error) => {
	Console.WriteLine("Write succeeded: " + success);
	if(error != null)
	{
		Console.WriteLine(error);
	}
});

I trust it’s obvious that the types of data you attempt to store must match those you’ve requested permission from the end-user and that your error-handling should be considerably more sophisticated (since it’s incredibly possible that app users are going to be very cautious about allowing access to their medical data, even if it’s clearly central to the app’s value).

The resulting shared data (assuming that permissions are granted) looks like this in the Health app:

image1

Notice that although I created the data using Fahrenheit, in this case it’s being displayed as Celsius (which I imagine is the opposite of the likely use-case!). Units of measure and conversions are built in to Health Kit, which I’ll cover in a later post. For now, though: Happy Healthing!

The Protocol Pattern

In C# (and F#), one can define extension methods on interfaces. These extension methods can have implementations, which can be used as default implementations for implementors of the extension. I haven’t heard a name for this technique.

Example:

interface IFoo
{

}

static class IFoo_Extensions 
{
	public static void Foo(this IFoo self) { Console.WriteLine("Foo"); }
}

class ImplementingClass : IFoo
{

}


class MainClass
{
	public static void Main (string[] args)
	{
		var aFoo = new ImplementingClass ();
		aFoo.Foo (); //Prints "Foo" from extension default implementation

	}
}

Xamarin uses this pattern extensively when binding Objective-C Protocols, which are essentially interfaces with optional methods. For instance, if you have an interface where some methods must be implemented by the library user but some aren’t, you can do this:

interface IFoo
{
	//Methods defined here, as always, must be implemented
	void Necessary ();
}

static class IFoo_Extensions
{
	//"Optional" methods defined here with default implementations
	public static void Optional (this IFoo self)
	{
	}
}

class ImplementingClass : IFoo
{
	public void Necessary ()
	{
		Console.WriteLine ("Necessary");
	}

//    public void Optional()
//    {
//        Console.WriteLine("Overridden");
//    }

}

Obviously, it’s not exactly the same to have a default implementation defined in an extension method as it is to have an optional method that simply does not exist. But conceptually it’s close enough that I’ve started referring to this technique as the “Protocol Pattern.”

Thoughts?

Local Notifications in iOS 8 With Xamarin

As of iOS 8, the user has to provide explicit permission for apps to respond to local notifications. This means that now, the first time the program is run, you need to run code such as:

//F#
UIUserNotificationSettings.GetSettingsForTypes(
    UIUserNotificationType.Alert
    ||| UIUserNotificationType.Badge
    ||| UIUserNotificationType.Sound,
    new NSSet())
|> UIApplication.SharedApplication.RegisterUserNotificationSettings

or

//C#
var settings = UIUserNotificationSettings.GetSettingsForTypes(
    UIUserNotificationType.Alert
    | UIUserNotificationType.Badge
    | UIUserNotificationType.Sound,
    new NSSet());
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);

Which will present a user dialog. When they complete that dialog, the system will call the UIAppDelegate.DidRegisterUserNotificationSettings method. You can check the status using UIApplication.CurrentUserNotificationSettings.

If you try to send a notification without these settings being allowed, you will get a runtime error of the form:

Attempting to schedule a local notification {...} with an alert but haven't received permission from the user to display alerts
Attempting to schedule a local notification {...} with a sound but haven't received permission from the user to play sounds
Attempting to schedule a local notification {...} with a badge number but haven't received permission from the user to badge the application

F# For Scripting

It’s F# Week at Xamarin. Also, in the US, it’s only a 4-day work-week. F# saves 20% of your time. QED.

Anyway, I don’t have any actually interesting F# to share, but I recommend:

But what I thought I could quickly contribute is that:

  • F# is an awesome scripting language; and
  • Scripting may be the best way to learn F#

Scripting tasks often involve transforming a stream of text by repeatedly Filtering, Assigning, Reducing, Transforming, and Slicing it (“a sequence of FARTS“) and this is an area where the functional approach is pretty clearly easier to work with than the OOP approach of a network of cooperating objects.

And since scripting tasks are often private or semi-private low-complexity chores, they’re an excellent domain for regularly exercising your knowledge of a new language. It’s all well and good to carve out a couple weekends and work through a book but nothing beats regular exposure.

(While I’m on the subject, these are currently my favorite F# books. Initial exploration:

Deeper dives:

)

F# scripts are F# files with the .fsx extension. On OS X with mono, they can be run with fsharpi script.fsx or:

#if run_with_bin_sh
  exec fsharpi --exec $0 $*
#endif
printfn "%A" fsi.CommandLineArgs

To add references, use #r:

#if run_with_bin_sh
  exec fsharpi --exec $0 $*
#endif

#r "System.Core.dll"
#r "System.Xml"

open System
open System.Xml.Linq
open System.IO

//...etc...

I’ve been using F# for scripting for more than a year now and I can honestly say that it’s displaced Ruby as my scripting language of choice.

Give it a shot!