Why would you possibly want to write JavaScript on the your phone? For very good reasons: Pebble watch apps can generally do very little by themselves. Instead they communicate with a custom app that runs on the phone, and that custom phone app does stuff on behalf of the watch app.

For example if I wanted to write an Evernote client than ran on the Pebble watch, I’d code the watch app in C, and then create a custom Android app in Java. My watch app could talk to my Android app, which could in turn talk to Evernote. This is in fact what I did in an experimental client I talked about recently at a conference.

Android and iOS

But the Pebble doesn’t just support Android: it also supports the iPhone. If I wanted to extend my app to iOS I’d need to write an equivalent app in Objective C, or C#. I’d have to duplicate my coding and testing. There are also Bluetooth issues on iOS with the Pebble, which stop more than one app from communicating with the watch at a time, and the app needs to be whitelisted.

So when Pebble announced that they supported writing JavaScript apps that ran on the phone, hosted within a JavaScript engine that ran within the Pebble phone app on both Android and iOS, this seemed appealing. I’d not need to write a custom Android app, and a custom iOS app. Instead I could code up the phone functionality in JavaScript, and all would be good.

But first, I need to check that I could talk to Evernote’s cloud API using the Pebble JavaScript implementation …

Evernote and Thrift

The Evernote service API is exposed using a technology called Thrift. Originally developed at Facebook, and now hosted by the Apache Foundation, you define your API using a Thrift Interface Definition Language (IDL). This IDL is consumed by Thrift code generators which generate language-specific bindings allowing you to access the interface from Java, C#, PHP, and many other languages, including, of course, JavaScript. The generated code talks to a Thrift runtime, which sends and receives bits over the wire to the corresponding service.

I thought I’d start off by making the Pebble phone-based JavaScript app talk to Evernote, and then once I had that working, I could make it talk in turn to my C watch app.

I downloaded the Evernote JavaScript SDK from GitHub which contains both the generated “proxy” classes generated from the Thrift IDL, and the Thrift Runtime classes, both in JavaScript.

I decided to start simple, and just list my Evernote notebooks:

// Get these by creating an account and logging in to sandbox.evernote.com and then// going to https://sandbox.evernote.com/api/DeveloperToken.actionvar authTokenEvernote = "...";var noteStoreURL = "https://sandbox.evernote.com/shard/s1/notestore";

// We want to talk the Thrift Binary protocol over HTTP. These classes are in the// Thrift runtimevar noteStoreTransport = new Thrift.BinaryHttpTransport(noteStoreURL);var noteStoreProtocol = new Thrift.BinaryProtocol(noteStoreTransport);

// We want to talk to Evernote's NoteStore service. This is generated codevar noteStore = new NoteStoreClient(noteStoreProtocol);

I put this into a file I called main.js but I also needed to include the Thrift runtime (thrift.js and pebble-js-app.js) and the generated Evernote proxies (including NoteStore_types.js and NoteStore.js).

Since this release of the Pebble SDK only supports a single JavaScript file, named pebble-js-app.js, I borrowed a script volunteered by Matthew Tole that validated the JavaScript and merged all the files together in a single file, and built and ran the Pebble app:

The first error I hit when I tried running the code, is that the Thrift JavaScript runtime expects to be able to use the DataView class, which is part of the JavaScript Typed Arrays mechanism, a work in progress:

It turns out although it is not documented, or supported, that there is a partial Typed Array implementation: the Pebble JavaScript Engine has an implementation of the ArrayBuffer type, as well as Int8Array, Uint8Array, etc. There are some peculiarities, such as the ArrayBuffer supporting the slice method, but not the byteLength property.

So I went looking for an ArrayBuffer implementation I could use, and came across Joshua Bell’s implementation on GitHub.

I included it in the build script, but it did nothing. Upon further examination, I discovered that it looks to see if there is an existing implementation and (very politely) does nothing if it finds one. I didn’t want that:

The concept of having your watch app talk to JavaScript code, which in turn talks to the outside world is very appealing. It means that you don’t have to write, test and maintain separate iOS and Android “companion” apps for your watch app.

I am sure that for most web based services what Pebble provides will be more than enough. Unfortunately for binary based interfaces, such as the Evernote interface, the current XMLHttpRequest support isn’t quite rich enough.