The Ionic Eddystone Endeavor

For as long as they've been around I've been interested in beacons. Advancing the promise of the traditional RFID, beacons have the advantage of replacing the costly RFID scanner, which kept RFID out of the hands of the general public, with a simple bluetooth smartphone. Since becoming a cross platform mobile developer I've longed for the day when I could do a full beacon implementation in the Ionic framework. That day is here!

iBeacon Versus Eddystone

I was excited about Apple's iBeacon protocol when they first announced it back in 2013. Since then… crickets. Apple has failed to update or even mention their iBeacon framework in years and it's starting to feel like they've abandoned it. Also iBeacons have never received official support for Android devices. Some Android devices have gotten around this, but the support is unofficial and subject to Apple’s whims.

Google's Eddystone however is making strides, even implementing the ability to use beacons without an app. iBeacon transmits a simple UUID with major and minor numbers that differentiate the beacons in a given set, nothing more, nothing less. Eddystone however gives you the ability to transmit several types of packets. Eddystone-URL alone increases usability dramatically with its ability to transmit a URL as well as an identifier. Also, Eddystone is supported for iOS and Android, a major advantage.

iBeacon has one serious advantage on iPhone that we should talk about, and this is just on iPhone. While both implementations can scan for and range beacons while in a background state, iPhones at a system level have the ability to monitor beacons while in a killed state. At the risk of being redundant I'll clarify: iPhones have the ability to see your beacons and wake up your app. While initially I thought this would be a major disadvantage for Eddystone I remembered that the majority of users cough John Corbin cough never shut down an app. No matter how many times you show them at Christmas.

If you NEED to use iBeacons I recommend you check out the ionic native ibeacon plugin. It claims to work on both Android and iOS despite iBeacons not officially being supported on Android. However for this journey I decided to go with Eddystone.

Implementing Eddystone

Ionic does not currently have an Eddystone Native plugin. The beauty of Ionic though is that we have a wealth of Cordova plugins we can use, and lucky for us there is an eddystone plugin provided by the fine people over at Evothings.

I won't go over all of the implementation details of this since Paul Halliday has a great tutorial. Implementation is fairly simple; the only note I have on this tutorial is that Ionic doesn't automatically create a declaration.d.ts file anymore. To get around this simply put your declaration in the component file.

With Halliday’s tutorial you should be able to range a beacon and get an RSSI(Received Signal Strength Indication) and whatever else you have indicated to get from your beacons. That's about it. Lets go farther.

Local Notifications

A large part of beacons is notifications, the ability to be notified when a beacon is nearby, even when the phone is off. To do this we'll need two parts: local notifications and background mode.

Local Notifications are pretty self explanatory. The Ionic Local notification plugin works great and it's pretty simple to implement. Two commands (they're in the readme) and some normal importing into your component and you're ready to create notifications with this simple code:

// Schedule a single notification
this.localNotifications.schedule({
  id: 1,
  text: 'Single ILocalNotification',
  sound: isAndroid? 'file://sound.mp3': 'file://beep.caf',
  data: { secret: key }
});

Schedule is a confusing term here since it sounds like we're doing it for later notification. If a later scheduled notification is something you want then add an at: property to your scheduling. Without it the notification simply defaults to right now.

As of writing this the Ionic Native does not have a working background. WKWebView is a webkit based web view component for iOS that's been around for a while as an option for ionic developers. Unfortunately its optional nature meant a lot of plugins weren't made with it in mind, Ionic Native Background Mode being one of them. Recently Ionic made the brave decision to implement it as the standard and it's caused more than a few problems with old plugins. Mike Hartington has a great post about Ionic's decision and the speed enhancements alone justify the move.

In the absence of an ionic native implementation we'll have to dip back down into the realm of cordova. The Ionic Native implementation is a wrapper around the cordova plugin by Sebastian Katzer. Unfortunately this means the plugin shares the same problems, so we'll have to keep looking. I used a forked version here.

The readme for this forked version hasn't been updated completely. To install run:

cordova plugin add https://github.com/nottinhill/cordova-plugin-better-background-mode

Then I placed this code in the constructor:

let world = this;
this.platform.ready().then(() => {

    cordova.plugins.backgroundMode.enable();

    cordova.plugins.backgroundMode.on(("activate"), function() {
        world.backgroundRanging();
    });

    cordova.plugins.backgroundMode.on(("deactivate"), function() {
        world.stopScanningForBeacons();
    });
});

There's a lot going on here. First I assign scope to a variable to use it within the background mode. Once the platform is ready I enable the background mode, and then create two listeners. Activate and deactivate respond to the app being placed in the background and foreground respectively. The activate listener when called activates a special function that listens for beacons and creates notifications when one is present..

scheduleNotification(beaconAddress){
    this.localNotifications.schedule({
      id: 1,
      text: 'Beacon Ho: ' + beaconAddress,
    })
}

I passed in the beacon address in this implementation to identify each beacon in its notification.

Conclusion

That's it! That's all you need for a basic implementation of iBeacons in your app with local notifications.

The Contextual Web has the ability to create experiences that connect people back to their communities in new and interesting ways. Beacons deliver on that by giving people the information they need when they need it, and is more reliable than geolocation. This implementation is the beginning point for a full beacon project. Check out my github research project for more information.