Knowing .NET Sometimes a coder who writes, sometimes a writer who codes. Formerly, a coder who edited magazines.

May 7, 2015

How to: Handoff to a Xamarin iPhone app from Apple Watch

Filed under: C#,iOS,Xamarin — larry @ 6:00 am

# How to: Handoff to a Xamarin iPhone app from Apple Watch

There are two ways to activate the parent (aka container) app from an Apple Watch app. You can either directly activate the container app using WKInterfaceController.OpenParentApplication or you can use Handoff.

Using Handoff is a little more complex, so I thought I’d write a quick little how-to. There are a few different Handoff scenarios, but perhaps the most common for the  Watch is: “On my watch I want to begin a task that I complete later on my iPhone.” So, for instance, some task that requires either more data-entry than is appropriate for the watch or some capabilities not available on the watch.

I want to keep the focus on the APIs, so instead of a real-world sample, I’m going to create a minimal example: a button on the Watch activates handoff and a status label on the phone app is updated when the user activity is continued on the phone.

As always, we have a single Solution with 3 projects: the parent App, the Watch extension, and the Watch App.

Napkin 10 05-06-15, 4.21.12 PM

Every handoff activity has a unique identifier. By convention, this is a domain-reversed string such as: com.xamarin.HandOffDemo.verb.

To trigger the Handoff behavior, the watch extension calls the WKInterfaceController.UpdateUserActivity method, with its first argument set equal to this identifier:

partial void ActivateHandoffClicked (WatchKit.WKInterfaceButton sender)
{
    var userInfo = NSDictionary.FromObjectAndKey(new NSString(“value”), new NSString(“key”));
    this.UpdateUserActivity(“com.xamarin.HandOffDemo.verb”, userInfo, null);
}

The third argument is a NSUrl object that can be used for Handoff tasks that should be handled by Safari. But in our case, we’re handing the userInfo dictionary containing the very complex data associated with our handoff.

Your parent app registers its interest in this type of handoff within its info.plist. In the parent app info.plist, add a new array called NSUserActivityTypes and add to it a string with value com.xamarin.HandOffDemo.verb

Napkin 11 05-06-15, 4.29.20 PM

It’s possible that an app could be interested in certain handoffs, but not always be in a position to actually handle them. That logic can be placed in an override of the UIApplicationDelegate.WillContinueUserActivity method:

public override bool WillContinueUserActivity (UIApplication application, string userActivityType)
{
    //Yeah, we can handle it
    return true;
}

Assuming that we return true from that method, the next step is to override the UIApplicationDelegate.ContinueUserActivity method:

An architectural issue that needs to be addressed is that this Handoff re-entry point is in the UIApplicationDelegate object, which of course does not have an associated user interface. There are several ways to handle this, but as a fan of reactive programming, I think the proper design is to create either an IObservable sequence or a more traditional C# event, which is what I do here:

public event EventHandler HandoffOccurred = delegate {};

public override bool ContinueUserActivity (UIApplication application, NSUserActivity userActivity, UIApplicationRestorationHandler completionHandler)
{
    HandoffOccurred?.Invoke (this, userActivity.UserInfo);

    return true;
}

The third parameter, completionHandler used if you have references to custom UIResponder objects that should handle the user activity. In the case, you put those references in a NSArray and pass them to completionHandler, which will cause each of their ContinueUserActivity methods to be called. (Update: Apple would probably prefer this technique to my event, but I am not sure if it’s necessary, and it requires the UIApplicationDelegate to maintain a reference to the subscribing UIResponder, so you either have an ugly dependency or you have to implement some kind of Observer / Subscriber pattern. So I still would suggest an event or IObservable as the better solution.)

In the parent app’s main UIViewController class, I have:

public override void ViewDidLoad ()
{
    base.ViewDidLoad ();

    //Configure user experience for Handoff
    var myAppDel = (AppDelegate) UIApplication.SharedApplication.Delegate;
    myAppDel.HandoffOccurred += HandoffOccurred;
}

public void HandoffOccurred(object sender, NSDictionary userInfo)
{
    InvokeOnMainThread( () => statusLabel.Text = userInfo[“key”].ToString() );
}

And that’s all there is to it. Obviously, a real use-case would involve building a more complex NSDictionary holding the context of the watch interaction and a similarly complex handler in the parent app.

Now, when the Handoff is activated from the Apple Watch, my iPhone lock screen shows the icon of the parent app in the lower-left corner. If I drag that up, the parent app opens, the re-entry process begins, with UIApplicationDelegate.WillContinueUserActivity and UIApplicationDelegate.ContinueUserActivity.

January 21, 2015

Programming WatchKit with F#

Filed under: F#,iOS,Xamarin — larry @ 4:00 am

Disclaimer: This is just a hack. I’m not in any position to make announcements about stuff, but Xamarin loves F# and I’m sure that better solutions than this are forthcoming. But this was fun to get running, so…

Xamarin just released it’s Preview of Watch Kit support and naturally, I had to see if it was possible to use F# to program the forthcoming Apple Watch. Yes, it is.

As always with Watch Kit Apps, the Xamarin solution consists of three projects:

  1. A Parent app that is a normal iOS app;
  2. An Extension that runs on a connected iPhone and executes the program logic; and
  3. A Watch App that runs on the Watch and is essentially a remote display for the Extension App

You can read much more about this at Xamarin’s Watch Kit Documentation site.

To create an F# Watch solution, first create an F#-based Parent App. Then, add the Extension project to that app, an F#-based Custom Keyboard Extension. Finally, add a Watch App from the C#/iOS/Unified/Apple Watch solution template.

The Watch App consists only of a storyboard and resources. It doesn’t actually have any C# (or F#) code in it.

Follow these instructions to [set project references and identifiers].

Switching the Extension from Custom Keyboard to Watch Kit

You will have to manually edit the info.plist of the Watch Extension:

  • In NSExtension, switch the NSExtensionPointIdentifier to com.apple.watchkit; and
  • Under NSExtensionAttributes, add a WKAppBundleIdentifier key to the identifier of your Watch App (e.g., com.xamarin.FWatch1.watchkitapp)

Screenshot 2015-01-21 15.02.07

Now you can get rid of the template F# code and replace it with something like this:

namespace WatchX

open System
open UIKit
open Foundation
open WatchKit

type InterfaceController(ip : IntPtr) =
    inherit WKInterfaceController(ip)

override this.Awake (context) =
    System.Console.WriteLine("Hello F#")
    this.myLabel.SetText("F# |> I ♡")

Again, this is covered in much more detail in Xamarin’s docs, but every scene in the Watch App’s storyboard is backed by a subtype of WKInterfaceController. Since it’s loaded from a Storyboard, it uses the constructor that takes an IntPtr. The Awake method is called when the controller is instantiated.

The Hacky Part

Xamarin has not yet released designer support for Watch Kit, so for now, you need to edit your Watch App’s Storyboard in XCode Interface Builder.

That’s not the hacky part.

Once you’ve designed your UI, you have to hand-edit the Storyboard XML, adding connections elements that define your outlets (properties) and actions (event-handlers). You have to set the destination attribute to refer to the id of the associated control:

Screenshot 2015-01-21 15.37.52

But really, that’s the only ugly part! ;-)

Back in your Extension app, you now have to use attributes to link up your F# code with elements within the Storyboard. The RegisterAttribute on your WKInterfaceController links to the customClass attribute of the controller element, and the name of your OutletAttribute properties must correspond to the property attribute of the outlet elements. Finally, the selector attribute of your action elements must have a corresponding ActionAttribute :

    namespace WatchX

    open System
    open UIKit
    open Foundation
    open WatchKit

    [<register ("InterfaceController")>]
    type InterfaceController(ip : IntPtr) = 
        inherit WKInterfaceController(ip)

        let mutable label : WKInterfaceLabel = null
        let mutable button : WKInterfaceButton = null

        let mutable clickCount = 0
       
        [<outlet>]
        member this.myLabel with get() = label
        member this.myLabel with set(v) = label < - v

        [<Outlet>]
        member this.myButton with get() = button
        member this.myButton with set(v) = button < - v

        [<Action("OnButtonPress")>]
        member this.OnButtonPush () =
            clickCount < - clickCount + 1
            sprintf "Pressed %d times" clickCount 
            |> this.myLabel.SetText 


        override this.Awake (context) = 
            System.Console.WriteLine("Hello F#")
            this.myLabel.SetText("F# |> I ♡")

And that’s really all there is to putting F# on your wrist!

Github project

December 20, 2014

Experiment in Auto-Generated UML as a Documentation Tool

Filed under: Uncategorized — larry @ 8:46 am

I wrote a program to automatically generate class diagrams, filtered by coupling. Here is the result for CoreBluetooth in iOS:

 

Screenshot 2014-12-20 08.33.14

 

You can see there are clusters around CBPeer, CBPeripheral, and CBCentral and that CBCharacteristic is another class with lots of references.

Obviously, huge class diagrams are more noise than signal, but if I further filtered this down to specific topics…?

I dunno’.

 

P.S. Yeah, yeah, they should be open diamonds, not filled diamonds.

 

December 16, 2014

Good Bye, Dr. Dobb’s

Filed under: Uncategorized — larry @ 11:21 am

Today comes the shitty news that Dr. Dobb’s (…Journal of Computer Calisthenics and Orthodontia) is shutting down.

I would not have had the career I have had without DDJ: first as an inspiration, then as a competitor, and then as the last torch of technically rigorous, personally-voiced but professionally edited high-quality programming articles.

DDJ was the last of the great programming magazines and was, probably, the greatest. Only Byte could, perhaps, have an equal claim to the crown. All the rest of ours, an entire industry, envied their columnists, technical editors, and authors. Even the standouts (Microcornucopia, Programmer’s Journal, C/C++ Programmer’s Journal, Unix Review, PC Techniques, WinTech Journal, and, … hell, it’s my feed… Computer Language, Software Development, and Game Developer) could only occasionally match their quality.

Perhaps what I admired most about Dobb’s was that it never wavered from being a programming magazine. In the early 90s, I decreed that Computer Language would never again refer to our profession as “programming,” it would only be referred to as “software development.” We published articles about management, about architecture and design, we boasted (boasted) of how little source code we published (because we talked about “the real issues”). And while I think there was a valid point to be made, the truth is that programming — the infinitely challenging alchemy of turning sparks traveling through blocks of sand into computation and information  — is what drew me to the profession, why I will code when I retire, and why I would have a computer under the floorboards if programming were illegal. Dr. Dobb’s understood, and celebrated, that mysterious joy. Perhaps that is why it out-lasted all the rest.

Now, it seems like, if our industry has a face, it’s the face of an arrogant Silicon Valley douchebag who knows everything about monetization, socialization, and micro-localization and nothing about algorithms, memory models, and programming languages. Dr. Dobb’s wasn’t a magazine for venture capitalists or “Digital Prophet”s or “Brand-Story Architect“s. It was a magazine for hard-core coders, people who could appreciate the trade-offs in the design of a macro preprocessor, get an “ah-hah!” moment from reading an assembly language listing for a chip they didn’t know, or  grasp the theme of an implementation discussed over a year of columns.

It will be missed.

October 25, 2014

My talk “let awesome = App |> Seq.map F#” available…

Filed under: DotNet,F#,Xamarin — larry @ 10:32 am

Video from my Xamarin Evolve talk on using F# for programming mobile apps, in which I argue that functional and object-oriented programming are two great paradigms that pair great together.

August 27, 2014

Xamarin.Forms Programming in F#

Filed under: F#,iOS,Xamarin — larry @ 4:02 pm

Things are kind of busy what with Evolve being only 40 days away and iOS 8 coming down the pipe, but I thought I’d share the easy hack that allows you to program Xamarin.Forms with F#.

(Of course, Xamarin loves F# and official support and templates and documentation and all that sort of stuff is forthcoming. This is just something you can do for the moment to begin exploring Xamarin.Forms with F#.)

tl;dr: Use the beta PCL 78 F# Core and link to the facade assemblies for monotouch

OK, so assuming that was a bit too brief…

In Xamarin.Studio create a “New solution…” of type F#/iOS/iPhone/Empty Project…

Open the “References” folder and delete the existing reference to Fsharp.core.dll.

Right-click the solution and select “Add Packages…”

Screenshot 2014-08-27 15.42.39

 

In the NuGet dialog, select “Show pre-release packages” and type FSharp.Core into the search box. This should allow you to add the “FSharp.Core Mono delay signed” package.

Screenshot 2014-08-27 15.25.05Also, add the Xamarin.Forms package:

Screenshot 2014-08-27 15.46.26

And now the tricky part!  You have to add references to the System.ObjectModel.dll and System.Runtime.dlls from the monotouch facade assemblies by hand.

Right-click on the References folder, Select “Edit…”, and select “.NET Assembly”. Add references to System.ObjectModel.dll and System.Runtime.dll from, in my case:

/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.5/Facades/

Your path may be a little different.

Write a Xamarin.Forms app in 36 lines of code :


namespace FSXF1

open System
open MonoTouch.UIKit
open MonoTouch.Foundation
open Xamarin.Forms

type App = class
 static member GetMainPage =
   let lbl = new Label()
   lbl.Text <- "Hello, F# Xam.Forms!"
   lbl.VerticalOptions <- LayoutOptions.CenterAndExpand
   lbl.HorizontalOptions <- LayoutOptions.CenterAndExpand

   let cp = new ContentPage()
   cp.Content <- lbl
   cp
end

[<Register("AppDelegate")>]
type AppDelegate() =
 inherit UIApplicationDelegate()

 member val Window = null with get, set

// This method is invoked when the application is ready to run.
 override this.FinishedLaunching(app, options) =
   this.Window <- new UIWindow(UIScreen.MainScreen.Bounds)
   Forms.Init()
   this.Window.RootViewController <- App.GetMainPage.CreateViewController()
   this.Window.MakeKeyAndVisible()
   true

module Main =
   [<EntryPoint>]
   let main args =
     UIApplication.Main(args, null, "AppDelegate")
     0

And you’re good to go!

Screenshot 2014-08-25 10.16.14

 

P.S. If it helps: https://github.com/lobrien/HelloXamarinFormsFSharp

July 11, 2014

Exploring HealthKit With Xamarin: Provisioning and Permissions Illustrated Walkthrough

Filed under: iOS,Xamarin — larry @ 9:45 am

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!

July 10, 2014

The Protocol Pattern

Filed under: C#,DotNet,Xamarin — larry @ 6:32 am

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?

July 3, 2014

Local Notifications in iOS 8 With Xamarin

Filed under: iOS,Xamarin — larry @ 8:19 am

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

July 2, 2014

F# For Scripting

Filed under: DotNet,F#,Xamarin — larry @ 12:59 pm

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!

Older Posts »

Powered by WordPress