Creating an App Clip for Hue lights

As you might know, we develop the Philips Hue cloud at Q42. This IoT platform allows people to control their connected lights from anywhere. Over the years, Philips' innovation has grown into a robust infrastructure that easily operates many hundreds of thousands of Hue lamps worldwide.

As software engineers, we love to play with innovative technologies like Philips Hue. In this regard, our highlight of the year is w00tcamp, a two-day hackathon with colleagues and some friends of other agencies. During w00tcamp we turn ideas and new technologies into cool prototypes. Of course, last year’s w00tcamp was completely remote, with all Q-ers working from home.

My colleague Herman, part of our Philips Hue team, had an idea to apply Apple’s new App Clips to Hue lights to solve a problem he was facing: the lack of a “guest mode”. When guests stay at your home, they have no easy way to change the settings of the Hue lights. With Hue, you can’t really use the switches on the wall anymore. And installing the app and authenticating is a hassle if you’re a guest.

What if scanning a code could pop up an app that would allow control of the lights? With no installation, login or anything else needed. That’s where App Clips come in.

In this article I share our learnings of building an App Clip for Hue lights.

What’s an App Clip?

App Clips are a new feature of iOS 14 that Apple announced at WWDC 2020. They are lightweight iOS apps that don’t require installation from the App Store. App Clips are temporarily installed on the device, allowing users to use a piece of native app functionality at the moment they need it, similar to Instant Apps on Android.

This opens up lots of interesting new use cases. For example, an App Clip allows you to order something at a restaurant by scanning a QR-code on the table without going through the hassle of downloading the complete app. Or it can let you pay at a parking garage using Apple Pay.

App Clips can be launched quickly using a link, QR-code or NFC tag as an entry point. They can also be customised per location.

The easiest way to open an App Clip is via a URL. If you’ve implemented universal links for your app and have added an App Clip to it, the user will be offered to launch the App Clip (if they don’t have the app installed). Otherwise, the main app will launch.

You should take some time to consider how your use case fits in the App Clip system.

An important point is that you cannot create a ‘standalone’ App Clip in the App Store. It has to be part of a parent app.

What have we built?

A downside of Philips Hue is that it doesn't play well with traditional light switches on your wall. You have to buy Hue switches separately and mount them somewhere. This is fine if you own the house, but annoying if you’re a guest. Since the only way to control the lights is to install the Hue app and connect it to the Hue system.

Using Hue Clips, a guest can simply scan a QR code with their phone and instantly control the lights in that room. The Apple App Clip code even has a super cool animation.

Using Hue Clips by scanning a QR code

You can try it for yourself by scanning one of these demo Hue Clips using an iPhone running iOS 14 or higher!

An Apple App clip code that will open the Hue Clips demo when scanned

The core idea is that you can create Hue Clips that correspond to rooms in your home. Scanning the code allows anonymous control of just the lights in a specific room.

There are three parts that make this work:

  1. A domain name with universal links enabled, so that it links to the App Clip.
  2. An iOS app with an App Clip packaged inside.
  3. A backend that lets the App Clip talk to the Philips Hue API over the internet.

Our App Clip is launched from a URL encoded in a QR code.

In order to make this work, you need to associate your domain name with the App Clip, which is done by serving a so-called associated domain file from your site. This file tells iOS that this domain belongs to your app, and how it can open certain links with your app or app clip.

It needs to be a JSON file hosted at the path /.well-known/apple-app-site-association. For example: https://hueclips.app/.well-known/apple-app-site-association

Within this JSON file, we add the sections for ‘applinks’ and ‘appclips’:

{ "applinks": { "details": [ { "appIDs": [ "8J6VSUTQNX.com.q42.hueclips" ], "components": [ { "/": "/c/*", "comment": "Hue Clip URLs" } ] } ] }, "appclips": { "apps": [ "8J6VSUTQNX.com.q42.hueclips.lightsclip" ] } }


App Clip

Recall that your App Clip is basically a lightweight iOS app. To handle the incoming URL after opening the App Clip, we can catch the URL in the SceneDelegate just like you would in a regular iOS app:

func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { guard let url = URLContexts.first?.url else { return } handleUrl(url) } private func handleUrl(_ url: URL) { guard let result = URLParser().parse(url) else { return } switch result { case let .lights(parameters): appState.bridgeParameters = parameters UserDefaultsConfig.lastUsedToken = parameters.token } }


The incoming URL contains a token, which can be used to control the lights via our backend API. We first try to parse the token from the URL and set it on the appState object, which is injected into our SwiftUI views as an environment object. This way, the UI automatically responds.

We also store the token in UserDefaults to recall it when the user re-opens the App Clip at a later time. The App Clip remains on the phone for some amount of time and will automatically be removed later.

Using the token parsed from the URL, the App Clip can now connect to our backend API to control the lights!

Backend

The backend at hueclips.app has an admin portal that lets users sign in with their Philips Hue account using OAuth2. They can create Hue Clips in this HueClips admin portal.

The job of the backend is to validate the token, and proxy Hue API calls to the Hue cloud, and from there onto the user’s Hue system inside their home.

🇳🇱 👋 Hey Dutchies!
Even tussendoor... we zoeken nieuwe Q'ers!

What did we learn

App Clips have to be packaged within a parent app
An important consideration is that an App Clip cannot exist on its own. It must be part of a parent app that is available in the App Store.

This was an issue for us, because our idea was “App Clip first”, so to say. We had to develop a parent app with enough functionality to justify its existence. So we added features to the parent app to let you sign in with your Hue account and create Hue Clips of your own.

App Clips must be under 10MB
App clips are limited to 10MB in size. This wasn’t a problem for our brand new app, but it will be a problem for apps that have some legacy. The apps that we’ve maintained for years for our clients often have accumulated a bunch of libraries that they depend on, and images/assets. You’ll need to minimise those to stay under the limit of 10MB.

Apple’s App Clip codes can only contain very little data
We didn’t find this in Apple’s documentation, but we could only fit a maximum of 35 characters in an Apple App Clip code. Unfortunately, that’s not enough for our Hue Clip codes. Because the token allows access to someone’s lights, it should be difficult to brute-force. Using our domain name hueclips.app, we had only 12 characters left for the actual token. This leaves few enough possibilities that you could ‘guess’ Hue Clip URLs by brute-forcing them. So that was definitely a no-go for our use-case!

New technology pitfalls
We used this app as a testbed for a bunch of new stuff that we haven’t used much: SwiftUI and Combine. This had quite a learning curve. We also ran into things that just weren’t mature yet, missing features or bugs.

In my experience, navigation in SwiftUI 2.0 is still a pain. It will get better, but my recommendation is to use UIKit for navigation.

Useful development tools
Apple offers some useful tools for testing your App Clips during development. You can put an iPhone in developer mode by connecting it to a Mac, and in the organizer in Xcode, select ‘use for development’. This enables the developer menu in the Settings app on the phone. There, you can configure the App Clip experience using a title and image to preview it before you upload the final version to the App Store.

Also, iOS has a special code scanner that you can add to Control Centre. You can find it in Settings > Control Centre. During development, you will need this to launch your App Clip from a QR code or App Clip code. It won’t launch when scanned using the normal camera app.

My 2 cents

Just like Android Instant App, Apple’s App Clip offers a native-like experience without the need to install an actual app. In our case it clearly adds value when easy control of Hue lights is needed for a certain time or space.

We think that Apple made a smart move in offering this technology. App Clip comes with handy development tools, re-usable UI components, and the option to use SwiftUI.

There are some pitfalls, though. For one, it’s hard to determine the size of your App Clip in advance. Because of the maximum of 10MB, making an App Clip poses a challenge for legacy apps, as these usually have a larger code base.

Another thing to remember is that not all features of iOS can be used. So it’s extra important to sharpen the focus of what you want your app to do.

We think the best use cases for an App Clip are short interactions as well as location-specific situations. After all, users don't want to install an app for places they don't visit often. Thus, App Clip is a great solution for ordering in a restaurant or paying for a parking space. Or for controlling Hue lights at a hotel or a friend's house.

After creating our App Clip for Hue lights, we're looking forward to developing an App Clip for the Dutch postal company PostNL. Last year’s Android Instant App was a big success. More users were eventually converted to install the real app. We expect the same result of an App Clip on iOS.


Do you also love working with new technologies like App Clips? Check our job vacancies (in Dutch) at werkenbij.q42.nl!