Turn Apple TV Into an iBeacon
Although not officially supported in tvOS, it is possible to turn your Apple TV into an iBeacon, creating an opportunity for interesting applications for home use.
The number of frameworks that were removed from tvOS is pretty staggering when you look at the API diffs. Most things like iAd will not be missed, but there were quite a few people disappointed that WebKit was something excluded. When I started doing some brainstorming on some potentially interesting use cases for Apple TV, I saw with relief that CoreLocation and CoreBluetooth are still part of the SDK. I assumed that because they were still present that the iBeacon APIs would be in there for creating and observing iBeacon geofences.
I was sorely disappointed when I loaded up Apple's AirLocate sample application and discovered that all the CLBeaconRegion
APIs are annotated with __TVOS_PROHIBITED
. Sad face.
Undeterred, I decided to explore the possibilities of using CoreBluetooth to manually set it up to advertise as a beacon. I fired up the AirLocate application on my iPhone and set a breakpoint on just where the peripheral data is created. Normally, you'd create a CLBeaconRegion
instance with the appropriate UUID, major, and minor, calling its peripheralDataWithMeasuredPower:
method to produce the data that CoreBluetooth needs to advertise as a beacon.
This dictionary payload has a single key, kCBAdvDataAppleBeaconKey
paired with a 21 byte NSData
object containing the iBeacon information. The debug output of this dictionary appears as follows:
kCBAdvDataAppleBeaconKey = <e2c56db5 dffb48d2 b060d0f5 a71096e0 007a03c3 c5>;
After capturing that information in the console, I created a sample application that similarly created a CBPeripheralManager
instance and started advertising with the information. It worked!
Once I knew it was possible, the next task was to discover how all the advertisement is encoded. The first 16 bytes of data is the UUID, which is pretty obvious. The next five bytes contain the major, minor, and measured power, in this case, 122, 963, and -59, respectively, in the example above. (Thanks to Blended Cocoa for the encoding for those last five bytes!)
Armed with this knowledge, I was then able to configure a custom beacon with the requisite data and turn my Apple TV into any iBeacon of my choosing! Your mileage may vary on this actually passing App Store review and could potentially stop working altogether. When OS X Mavericks came out a number of apps sprung up that could turn your Mac into an iBeacon, but suddenly stopped working when Yosemite came out.
You can download a sample project from GitHub here.