18 Nov 2016

It's Time for a Common Framework for Mobile and PC Apps

Suppose you want to build a native app for both mobile [1] and PC. You generally have to build two apps. You can share business logic, network and storage code, but not UI. Even when both platforms use the same language, as with iOS and macOS. The UI needs to be rebuilt completely from scratch. Even the parts that aren't different. That makes no sense. It's like reimplementing a linked list for mobile vs PC.

Earlier, this was not a big deal, since mobile and PC were different in so many ways.

The first aspect is screen size. Earlier, UI layouts built for such a tiny screen wouldn't be useful on a PC, or vice-versa. So being unable to share UI code between mobile and PC wasn't much of a constraint in practice. But now, the iPad comes in a 13-inch screen size, the same as many laptops. Apps running on the 13-inch iPad often have a similar UI as ones running on a 13-inch Macbook. For example, Apple's Notes app has a similar three-pane layout. So do many email apps, with a two-pane layout. Safari or Chrome on the 13-inch iPad looks essentially the same as on a Macbook. So does Google Maps. And so on. In today's world, it no longer makes sense to reimplement from scratch two very similar UIs. Ideally, you'd have only one implementation of whatever's common, with only the parts that are different being reimplemented. Reimplementing the whole UI makes as little sense as Google Maps reimplementing all its UI separately for Chrome and Safari.

The second aspect of convergence is touch. Earlier, mobile devices had touch, and PCs didn't. But for a few years now, Windows laptops and Surfaces have had touchscreens. So, an ideal Windows app would work great with touch. Not as an afterthought, but a great touch experience, with big enough touch targets, gestures and so on. Which mobile apps need to do as well. You might as well reuse the code.

The third aspect of convergence is right-click. Earlier, mobile devices didn't support right-click. But with Android apps coming to Chromebooks, it will be mainstream for mobile apps to have to work with right-click.

The fourth aspect of convergence is CPU performance. Earlier, mobile devices had slow CPUs, but today, the iPhone 7 Plus matches the latest Macbook Airs in performance [2]. Conversely, some laptops have now taken a step back in performance by switching to fanless processors. Processor speed is no longer a clear, marked difference between mobile and PC.

The fifth aspect of convergence is memory. Earlier, mobile devices had little memory, like 256MB. But now, the 13-inch iPad has 4GB — the same as many laptops. The iPhone 7 Plus is close, at 3GB.

The sixth aspect of convergence is storage size. Earlier, mobile devices had little storage, like 8GB, but now, both iPhones and iPads have a 256GB option, which is double that of the Macbook Air, and same as the Macbook Pro [3].

Seventh is storage speed. Sequential reads on the iPhone 7 Plus have been benchmarked at 400MB/s, much more than any hard disc.

In all these aspects, mobile and PC have converged. When the hardware is much closer, and the UX is much closer, it's time for the programming environments and frameworks to converge as well, so that you can reuse rather than reimplement.

Ideally, you'd reimplement or have different code paths only for the parts that are different. If you want a button to be bigger on a touchscreen, you should do [4] [5]:

if (touchscreen)
    button.size = 44x44;
    button.size = 30x30;

Everything else should be reused — creating the button, setting the label for it, registering a callback, and adding it to a container to display on screen. All that, which is common between mobile and PC, should be reused.

To be clear, this is not about building an app for one platform and making it run on the other without regard for the latter's UI conventions or human interface guidelines. Or building a least common denominator app, which will be sub-optimal on both mobile and PC. Those approaches lead to crappy apps. I'm not interested in second-tier apps.

Rather, I'm interested in building top-quality apps. Reusing UI code doesn't come in the way of that. In fact, it helps because, freed from the time waste of writing, debugging, optimising and maintaining redundant bodies of code to do the same thing, you can then spend the time improving the UX in other ways. This is the same argument as with eliminating any duplication of code, not just UI code.

Imagine an email app that lets you perform the following actions on a thread in the inbox:

  • Swipe the thread to the side, to archive it (on a touch-screen)
  • Long-press to open a context menu (on a touch-screen)
  • Right-click to open a context menu (with a mouse)

We'd code it as:


if (touchscreen)

The first line of code register a callback for a context menu, which will be triggered in the natural way for the device — right-click if there's a mouse, and tap-and-hold if it's a touchscreen. Or both, if the device has both a touchscreen and a mouse. The app doesn't need to understand and separately handle these three cases. They can be abstracted by the UI framework. The app can work at a higher level of abstraction — a context menu — without worrying about how it's triggered.

This will work on devices with a touchscreen, mouse, or both. And provide the best UX on each — mouse users can right-click, and touchscreen users can either tap and hold or swipe.

Mouse users aren't being forced to awkwardly swipe with a mouse — that would be forcing the wrong UX on that device. Similarly, touchscreen users can use a natural interaction — a swipe gesture — for their device. This is an example of how a common codebase can provide a top-tier UX on both mobile and PC. It's not true that you need to maintain separate codebases for that, or that a common codebase will be the least common denominator.

All that was about coding. Let's move on to other aspects.

Like QA. Once the code is written, you should use test [6] it extensively on all the platforms it will run on — phones, tablets and PCs — to see if it has the best possible UX on each. Not just test on one and hope for the best on the others. Because that will produce a crappy app. Reuse of code shouldn't be an excuse to skip testing to see whether it has a natural UX on each device.

After QA comes deployment. There are two possibilities. One is having separate app stores for mobile and PC, like Apple's iOS and Mac app stores. In that case, you'd separately submit two binaries [7] to both stores, wait for app review, fix any problems that surface, and go live.

The other possibility is a unified app store, with one binary, one app review, and one public launch.

In summary, since mobile and PC have converged, the application frameworks you use to build an app should converge as well, to reduce duplication of redundant code, to save time and produce better apps.

[1] Which includes tablets.

[2] This is the 13-inch model, with the base Core i5 processor, not the i7 upgrade. I'm comparing single-threaded performance, which is a better indication of responsiveness and user-perceived performance than multi-threaded performance.

[3] This is the cheapest configuration of the Macbooks, but it's still noteworthy for a phone to have as much storage as a Pro laptop.

[4] Note that we're checking for the presence of a touchscreen, not whether we're running on a mobile device. After all, Windows laptops, Surfaces and Chromebooks often have touch screens. Web developers will be familiar with this principle — check for capabilities, not for platforms.

[5] It would probably be better to just use the bigger size irrespective of whether the screen supports touch. Bigger click targets are easier to click with the mouse as well. And the UI would be consistent across screen types, which is good.

[6] Both a formal QA with documented test cases, and just having everyone on the team use it extensively as a user, to spot rough edges.

[7] Which might be the same, depending on the details of the toolchain.

No comments:

Post a Comment