9 Aug 2014

Redesigning the iOS Multitasking APIs

(Disclosure: I work for Google, but on nothing mobile-related, and these are my personal opinions.)

iOS and Android have always taken different approaches to multitasking: Android lets apps run whenever they want, for however long they want to. Android apps can ask the OS to start them up at a specified time, or in response to a specific event, like connecting to a Wifi network.

iOS multitasking, by contrast, is more restricted: apps can run in the background only in response to a fixed set of events, such as a geofence, audio playback in progress, etc. These set of events are far more limited than on Android.

With iOS 7, the OS also starts up frequently used apps in the background in an attempt to keep them updated by the time the user launches them. In any case, apps have no more than ten minutes to finish what they are doing.

Taking a step back from these details, the big picture is still the same: iOS multitasking is restricted, and the OS is in control, not the app.

Apple, and others, claim that the iOS multitasking API preserves battery life [1] and frees the user from having to manage background apps. And that it reduces cellular data usage.

Except that that argument is no longer true. As an iPhone user, I find myself having to actively manage background apps. A few months back, when my phone was fully charged when I went to bed, it would be around 90% when I woke up. After installing a few apps, like Moves (a pedometer app), it would drain to as low as 60% by the next morning.

This was such a problem that Moves has had to implement a power-saving mode of their own, which reduces tracking accuracy to save power. In any case, I uninstalled Moves, but still found the battery life to be not as good as it was a few months back. So I have to go on a witch-hunt to find out who the culprit is this time. Pedometer++? WhatsApp? Moment?

iOS sorely needs an Android-style battery meter that tells me which apps are draining the battery, so that I can uninstall them. Apple has recognized this, and is building a power meter into iOS 8 [2].

But building a power meter means acknowledging that the the goal of making the multitasking API seamless enough for users that they don’t have to manage background apps has failed. Maybe this was necessary to keep iDevices useful in ways users expect, such as apps that already have updated data when you open them, making use of more sensors, replacing standalone devices like Pedometers, making phones talk to other devices like watches, health and fitness devices, cars and so on.

Whatever the reasons, the originally stated goal of iOS multitasking — to free the user from managing background apps — has failed. What about the other stated goal — of reducing cellular usage? Does iOS at least achieve that? Unfortunately, no.

In my experience, iOS consumes more cellular data than Android. Maybe it’s because the Android OS itself is more careful about scheduling its activities and asks itself, “Does this need to be done right away, or can I wait for WiFi to be available?”. Or maybe it’s because Android’s multitasking is sophisticated and lets apps tell the OS to wake them up when WiFi is available. This applies to all apps that sync data — email [3], Twitter, Facebook, Dropbox, Simplenote, and so on. Let them sync over Wifi. In fact, it makes no sense for background data sync to happen on the cellular network when I’m almost always at a place where Wifi is available. The only traffic that should go on the cellular network in such a situation is traffic explicitly triggered my me when I’m out of Wifi.

When I switched from Android to iOS, I had to switch to a more expensive cellular data plan to accommodate iOS. And this happened both times I switched from Android to iOS, over the past few years. This is a failure of iOS.

Not only does iOS multitasking not achieve its goals of freeing the user from managing background apps and from controlling cellular data usage, but it also hurts the user experience. For example, I have Dropbox set to automatically upload photos. It works seamlessly on Android, to the extent that I never have to open the app. Whereas on iOS, I sometimes have to open the app to get the upload to work. If I don’t, iOS sometimes takes days to upload them [4].

Another example is apps like Simplenote, which constantly stay updated on Android, but not on iOS. If I enter something into Simplenote on my laptop and ask my mom to refer to it on her iPad, she sometimes opens it and says, “It’s not here.” I have to tell her to wait a few seconds after she opens the app. Wheres this is all seamless on Android, because of sensible multitasking.

And if the Internet connection happens to be down by the time she opens the app (which happens all the time in India), then the app will never show updated data. Whereas if it had synced earlier, in the background, it has a chance of working as the user expects.

So, to summarize, the iOS multitasking API fails to achieve both its goals: freeing users from managing background apps, and reducing cellular data usage. And it hurts the user experience, in the process. Who needs such a broken multitasking system?

What, then, is the solution? Full Android-style multitasking? Perhaps. But I can think of a couple of other ideas that are less controversial, because they are a smaller change from the status quo in iOS:

First, have an API that lets apps ask to be woken up when all four of the following conditions are met: the phone is fully charged, still plugged in to the charger, on Wifi, and locked. When this happens, all apps that want to run should be allowed to, and for as long as they want to, as long as the above conditions continue to hold.

Why would an app want to run for a long time? Well, for one, imagine syncing thousands of photos up to the cloud when you return from vacation. Or syncing many GB down from Dropbox when you get a new phone. This can take hours.

And there’s no downside to letting an app run as long as it wants to, in the above situation, since it doesn’t hurt cellular data usage, battery life or responsiveness. Or have the background traffic compete with foreground traffic for Internet bandwidth, slowing down the user’s browsing or those of other people at home.

A second API would be one that lets an app tell the OS, “Wait for N hours, and after that, wake me up when Wifi becomes available.” This API will achieve the goal of moving traffic from the cellular data network to Wifi. The OS can enforce a minimum wait time of two hours, say, to prevent apps from draining the battery by waking up too often.

A third API can let apps wake up in response to a push request from the server, when on Wifi. iOS has a crippled form of push, by coupling it to a notification. But there are many situations in which it’s not appropriate to nag the user, say if they haven’t enabled notifications for that app. Or if a routine event has occurred, which doesn’t merit interrupting interrupting the user, such as a note being updated in Simplenote on another device. So, loosen this restriction, when on Wifi: let the OS receive a push request from the server, and wake up the appropriate app, in the background, without showing any kind of UI to the user. Again, only when on Wifi.

Apps that always remain in sync, no matter when you open them, are seamless. Users no longer have to worry about ugly computer stuff like synchronization and apps being suspended when in the background. It becomes a seamless user experience: open Simplenote, and your data is always there, always updated. And if this seamless user experience can be achieved without costing the user money, there’s no reason not to do it. Again, the OS can enforce a limit, such as no more than one wakeup every hour, to prevent apps from being woken up hundreds or thousands of times, till the battery dies [5].

These three APIs — wake me up when fully charged and on Wifi, and wake me up after N hours when Wifi is available, and push on Wifi — would be a significant improvement over the status quo [6]. They’d reduce cellular data use, saving the user money. And they’d fix the crippled nature of the present iOS multitasking API, letting apps remain in sync more often, resulting in a better user experience.

[1] Another solution to this battery problem is to make the phones a few mm thicker, so that they last longer and we don’t need to worry so much about charging them all the time. Phones have become downright anorexic. While this may be good marketing, it’s one of those things that looks good in the shop but becomes a pain in day-to-day use. Make them a few mm thicker, so that we can worry about more important things in life than keeping our phones constantly charged. I’d much rather buy a 12mm phone than a 7.5mm one.

[2] The iOS power meter gives me statistics for a longer period of time — a week — than merely the time since the phone was off the charger. Statistics are more accurate over a longer period of time.

[3] If you’re thinking that email is a system app, it’s not always, like if you use the Gmail app on iOS.

[4] Perhaps in response to a location change. If I take some photos on friday evening in my apartment, they may not get uploaded till Monday morning, when I reach office.

[5] Imagine a heavily used email account where new mail arrives every minute or two. A naively implemented push would drain the battery by keeping the email app running all the time. So, it’s fine for the OS to impose a limit, such as only one wakeup per hour.

[6] The first of these three proposed new APIs does something the other two don’t — it lets apps run for an unlimited time.

No comments:

Post a Comment