I got the new Fitbit Ionic a few weeks ago, and I'm generally pretty happy with the device. I'm in the process of writing a full review of the Ionic, but I realized partway through that I had written quite a lot about the SDK, which many people probably won't be interested in. Hence, I decided to make that into its own post. In the meantime, if you're looking for a review, I would recommend reading DC Rainmaker's. He's a much more serious athlete than I am, and he reviews fitness gear semi-professionally, so he's able to put the devices through much more rigorous tests and go into detail about things like heart rate and GPS accuracy, which I won't be doing.
Anyway, the Ionic being Fitbit's first real smartwatch, I was eager to check out the SDK and dive into app development. And, well, I've tried to do so, but so far the results haven't been great. I think this is partly just because the platform is very new, and partly because of some questionable technology decisions that Fitbit made. Although it's too early to really evaluate the success or failure of the Ionic, or of FitOS an app platform, I think it can still be instructive to look at some of the choices that Fitbit made in designing the device and the OS, what effects they're having on developers now, and why I think they may prove to have been suboptimal choices.
Battery life was clearly the foremost concern for Fitbit when they designed the Ionic, and the technology decisions reflect that. Whereas the Apple Watch series 3 has a dual core CPU with a maximum clock speed of at least 780 Mhz, 3D graphics acceleration, and a rumored 768MB of RAM, the Ionic contains the humble Toshiba TZ1201XBG, with a meager maximum clock speed of 120Mhz1. The battery life of the two devices reflects these hardware differences: the Ionic lasts 4-5 days on a charge, whereas the Apple Watch lasts a maximum of 2 days. Personally, I think this was a great choice by Fitbit. Although the Apple Watch is inarguably a more capable "smartwatch," its two-day maximum battery life is an absolute deal-breaker for me, which is one of the primary reasons I bought the Ionic instead.
In fairness, Fitbit had a difficult problem to solve in developing an SDK for a smartwatch which supports multiple "companion" devices (i.e. iOS, Android, and Windows devices which communicate with the watch). First, there's the technical problem to solve of enabling the device to communicate with those three platforms, each of which has different restrictions on what apps can do. But perhaps equally important is the challenge of making the SDK easy and convenient enough that people will actually want to develop for it. Having an app platform is meaningless if nobody actually writes apps for it, and as Microsoft found out with Windows Phone, it can be very hard to attract developers to your platform if you're not already in a dominant (or at least strong) market position. Fitbit has been very successful with its cheaper wearables, but this is their first real smartwatch, and between Apple, Garmin, Suunto, Samsung, and dozens of others, there's a lot of competition.
The problem is that I don't think it's actually true that you can attract developers to your platform on the basis of it being easy to develop for—at least, not solely or primarily on that basis, and not the kind of developers you actually want to attract (that is, skilled developers who know what they're doing). The whole open source community is a testament to the insane amount of work that some software developers are willing to do for free, but everyone needs to eat. Developers will come to a platform if it provides a money-making opportunity, even if it's difficult to develop for; conversely, the easiest development platform in the world won't help if it has no users. With that in mind, it's also concerning that the FitOS platform has no built in way for app developers to charge for their applications.
And in any case, the biggest problem is that currently, the Ionic isn't actually easy to develop for, because the SDK is seriously short on features and extremely buggy. The web-based toolchain can also be pretty painful to use. In no particular order, here are some of the issues I've run into in the process of trying to develop a simple app, along with a few other problems that other developers have mentioned in the forums or in Discord:
- The DOM for an app's interface cannot be modified at runtime, so the only way to change your UI dynamically is to hide and show pre-existing elements. (Limited support for being able to spawn copies of existing elements is coming.)
- There is currently no built-in support for multi-page applications. Again, you just have to show and hide different elements to achieve the effect of multiple pages.
- I cannot get the OAuthButton component to work in my application settings, which means I can't authenticate to basically any web service. This might be iOS-specific; one of the Fitbit developers mentioned that their QA had reported something similar, so hopefully they're looking into it. Another developer mentioned having trouble getting OAuthButton to work with Fitbit's own REST APIs! Unfortunately, there are currently no examples of how this component is supposed to work. [Edited 2017-10-22] This appears to be fixed now.
- There is no emulator available, and no way to test the companion app or Settings page in the browser. This is an annoyance in general, and it seriously exacerbates the OAuthButton issue makes it really hard to debug any issue with REST APIs, because it also seems to be nigh-impossible to capture decrypted HTTPS traffic from an iOS device. (Granted, that last bit isn't Fitbit's fault at all, but it also wouldn't be an issue if the OAuthButton just worked.)
- PNGs are automatically converted to a proprietary hardware-accelerated format, but JPGs are not hardware accelerated so they take forever to load and can actually cause crashes or hangs if they're too big. This isn't a big deal for static images within the app, but what if you want to show content from the Internet?
- Communication between the watch and the "companion" app running on the phone seems to have some reliability issues. Sometimes the companion seems to just not launch at all.
- There is no way to "push" data from the companion to the watch. The watch app has to request the data, which means you need to poll for it if you don't know when the data will be available. (In fairness, this might be an iOS limitation.)
- Some APIs having confusing asymmetries. For instance, apparently in order to send a file from the companion app to the device, you need to manually CBOR-encode the contents before sending it. But when reading the file on the other side, it is decoded for you automatically.
- Documentation is fairly limited; for example, a lot of APIs have parameters that aren't well-explained, so you kind of have to guess what they do and then figure it out by trial and error.
- There is no local toolchain that you can install on your PC or Mac; there is only a web-based IDE which builds and deploys your app for you. This means no Git (unless you download copies of your code every time you make changes), no inline diffs, no using your own text editor with your own keyboard shortcuts, and no working on your app if you're offline. Some people have also reported connectivity issues when trying to get the watch to talk to the IDE.
- The IDE does not support breakpoints, performance profiling, or other such tools that you'd expect
from a modern development environment. I hope you enjoy debugging using
console.log(...)! By the way, there's a (relatively small) limit to length of string you can log.
I could go on, but I'm sure you get the point. Fitbit is aware of many (hopefully most) of these issues and is already working on many of them, and I have to commend their developers for being very responsive and involved in the community. There's an unofficial Discord channel where a few of the developers are very active in providing advice and investigating issues raised by the community. It's nice to have such a direct line to the development team; when interacting with a bigger company, you usually have to go through six layers of customer service and escalation engineers before you get to talk to an actual developer. Unfortunately, the downside is that the handful of Fitbit developers who are going above and beyond by fielding SDK questions during and outside of work hours can't possibly hope to keep up with the volume of requests they're getting, especially given how many issues there are right now. A public bug tracker would be nice so that we have a definitive source for which issues are being tracked...
So, what's the takeaway of all this? It's not that the Ionic is a bad device, or that its app platform is doomed to failure, or that Fitbit has bad engineers. I don't think any of those things are true. What I would like to communicate—and this will probably be a running theme in all of the CS-related writing I ever do—is that technology decisions really matter. Programmers are notorious for getting into religious wars about their favorite languages, and evangelizing your preferred technology too hard makes you come across as an asshole. I'm probably already guilty of this. But on the other hand, I feel that there's a strange sort of postmodern stream of thought in CS that it doesn't really matter what languages or technologies you choose to use in any given case, because they're all more or less equally capable, and that's… just not true.
Lest I come off as too much of a native code zealot, I'm not saying that native code is always the right choice. If you're writing a web application, or anything else that involves a lot of text manipulation, database interactions, or (de-)serialization of dynamic objects, you're probably crazy if your tool of choice is C++. Even just writing a client for REST APIs in C++ is not very fun (I know this from experience). But, particularly if you're building an app platform or a modding system or something like that, it's better to offer third-party developers as much flexibility and power as you can, rather than painting yourself and everyone else into a corner to start with. Remember that you can always just export C APIs and provide bindings to call them with your favorite scripting language. It's quite a bit more difficult to do the other way around.
The first personal computer I ever used was a Macintosh LCII, which had a clock speed of 16 MHz. That was 20-some years ago. If it doesn't blow your mind that we can now fit a CPU an order of magnitude more powerful than that in a watch, and make it run for several days on a tiny battery while powering several other sensors... well, it should! ↩