Modes, Quasimodes and the iPhone

A mode is a user-changeable state that influences how a computer reacts to user input. For example, if the Caps Lock key is active, all letters typed by the user appear in upper case. If it is not active, letters appear in lower case. Whether Caps Lock is active or not is not immediately obvious to the user, which often causes people to accidentally activate Caps Lock. This, in turn, causes unexpected results when users start to type.

Since modes can cause computers to behave in unexpected ways, they are typically frowned upon.

When Apple started to work on the original Macintosh, one of the team’s most important goals was to avoid modes. Famously, the original Mac did not even have a «rename file» mode. Instead, when a file was selected, typing anything on the keyboard would instantly change the file’s name. This caused a few problems, and Apple eventually recanted. On Folklore.org, Bruce Horn writes:

In the Finder, the startup disk would appear on the desktop, in the top-right corner, ready to be opened. The Finder would initially select it; once selected, typing would replace the current name, following the modeless interaction model that I had learned in the Smalltalk group from Larry Tesler. This meant that whatever anyone typed when they first came up to the Macintosh would end up renaming the disk.

This particular problem was solved by introducing a mode, but as a general rule, the Mac remained mostly mode-free. Following Apple’s lead, avoiding modes has been an important design goal in all modern computer systems.

Quasimodes

In some cases, modes are unavoidable. On desktop computer systems, quasimodes are often used when modes are not avoidable. Quasimodes are modes that are temporary and only exist as long as the user explicitly activates them. The aforementioned Caps Lock key introduces a mode. Its quasimodal counterpart is the Shift key, which introduces a transient mode that only exists as long as the user holds down said key. Since the user has to keep the quasimode alive explicitly, there is no chance that he or she will be confused by the mode.

A quasimode is thus a benign, harmless version of a mode.

Copy and Paste on the iPhone

We are so used to avoiding modes and using quasimodes instead that it often becomes hard to think outside of this box. When Apple famously claimed that the iPhone did not have copy and paste because it was difficult to find the perfect interaction model, a lot of mockups of how copy and paste might use popped up. Most of them used quasimodes to select text,1 often activated by touching the iPhone’s screen with a second finger. Even the Palm Pre uses a quasimode to select text: the «select» quasimode is activated by holding down the shift key on the keyboard.

Apple went a different way. Instead of using a quasimode, they introduced an actual, real mode. To select text, the user taps and holds the screen until the loupe appears. After releasing the finger, the iPhone either goes into a text selection mode, or displays a menu which allows the user to go into a text selection mode. This mode allows the user to move the start and end of the selection, and to cut, copy or paste using a popup menu.

But aren’t modes evil?

Not necessarily. Modes are not always bad. Modes cause issues if they make computers behave in unexpected ways. However, if the modes themselves are obvious to the user, if it is always clear how to exit the current mode, and if the modes interfere with as few of the user’s actions as possible, these issues disappear. In some cases, modes may even be preferable to quasimodes or to a non-modal interface.

Quasimodes require the user to do several things at the same time, such as holding down the Shift key while typing. Modes, on the other hand, allow users to do things sequentially - hit Caps Lock, type, hit Caps Lock again. Sequential actions, especially if guided well, are often easier to execute than parallel actions.

Additionally, the iPhone has very limited input mechanisms. Basically, the user interacts with most applications by touching the screen. While the iPhone can accept multiple touches at the same time, requiring multitouch interaction is often a poor idea. It makes it impossible to use the app with only one hand, it forces the user to obstruct larger parts of the screen, and it requires precise, coordinated user input.

Instead of overwhelming your users with a quasimodal or non-modal multitouch interface, it may often be a good idea to explore a guided modal interface which allows users to make choices sequentially. But keep a few things in mind:

  • The modes should be obvious
  • The modes should interfere with as few user actions as possible
  • If the user does something outside of the parameters of the active mode (such as tapping text outside the current selection in the iPhone’s selection mode), you should exit the mode immediately

If you use them carefully and with consideration, modes can be a useful and powerful interface design concept.

Note: This blog post contains a video that uses the <video> tag. Some feed readers such as Google Reader may strip these videos, and not all browsers display them. If you did not see a video showing the iPhone’s text selection mode, try opening this blog post in Safari or Firefox.



Don't Block User Interaction

I’m writing an iPhone app that interacts with a web service1. By necessity, that creates a lot of delayed interactions; situations where the user interacts with the app, the app contacts the server, the server responds, and the app shows the result with a noticeable delay. This delay creates room for strange situations. If the user selects an entry in a table view and the app doesn’t react immediately, the user may think that something went wrong and try to select a different entry. The same issue can be observed in web browsers where users repeatedly click on the same link, thinking the computer has not registered their first click if it doesn’t react immediately.

To make sure that my app does not behave in unexpected ways, I’ve looked into how other apps solve this problem. The following example is from a very cool Google Analytics client, conceptually similar to my own app. In this screenshot, I’ve touched «Today». The app responds by highlighting «Today», blocking all user interaction, and throwing up an activity indicator - a spinning wheel - to show that the app is working:

Blocking User Interaction

This clearly solves the problem. The user can’t select any of the entries while the app is interacting with the server, thus no unexpected situations can occur. However, blocking all user interaction means that there is no way to cancel the current action. What if I actually wanted to select «Dashboard» instead? What if the interaction takes too long and I want to do something else? The app won’t let me do that.

Not being able to interact with an app can be a frustrating experience.

In order to avoid blocking user interaction in my own app whenever possible, I’ve decided to show the new screen immediately after the user selects an entry. At first, the new screen will be empty, except for the «back» button. Again, an activity indicator is shown, but this time, there is no need to block user interaction since this screen has no existing state that could create unexpected situations if the user interacts with it:

Not Blocking User Interaction

If the user grows bored with waiting or remembers that he selected the wrong item, he can simply select the «back» button to go back to the previous screen. This will essentially cancel the user’s previous action and remove the current screen entirely, thus avoiding any problematic situations.

Apple uses the same «load an empty screen immediately, then load the data asynchronously» model. It should be noted that they don’t use a «naked» UIActivityIndicatorView though. Instead, they add a small «Loading…» text. It’s probably a good idea to follow Apple’s lead and mimic this behaviour:

Apple Not Blocking User Interaction

Whenever you find yourself blocking all user interaction, think about how you can avoid doing this. Sometimes it can’t be helped, but often, there’s a better way.


  1. No, it’s not the billionth iPhone Twitter client, it’s a FogBugz client. 



Safari 4 Release

Sven-S. Porst has a neat roundup of what’s new in the user interface of Safari 4’s release version.

While the beta version’s tabs may not have been the best possible solution, I really liked having them at the top of the window. Maybe Apple should have taken a look at Chrome.

One small note on the combined stop/reload button: Combining the stop and the reload button is a terrible idea. Sure, it’s impossible for both stop and reload to be active at the same time, so it seems like it would make sense. However, the button has a tendency to switch to reload just when you want to stop loading a page, which starts the page load all over again unless you quickly click stop again.

Apple has attempted to fix this problem in Safari 41. The stop/reload button doesn’t immediately switch from one state to the other anymore. Instead, there is a quick fade between the two states. During the fade, clicks on the button are ignored, so when you want to stop loading right when the button switches from «stop» to «reload», the click is mercifully ignored.


  1. At least I believe this was fixed in the release version. It may have been in earlier versions, too. 



Trust

Marco Arment writes about Apple’s approval process for iPhone applications. Worth reading.

There’s nothing wrong with an approval process for getting applications into Apple’s App Store. The problem here is an incredibly frustrating lack of transparency, and the utter absence of any kind of alternative. To developers, it feels like active hostility on Apple’s part. It’s difficult to invest large amounts of time into an application when you need Apple to publish it, but can’t trust them to ever do so, and can’t know what the rules for getting an application published actually are.

Here are some things Apple should do:

  1. Tell us what the specific rules are so we know exactly what will be published and what won’t. There has to be some kind of list of rules used by the people who approve apps; let us see this list.
  2. Let developers get pre-approval for application ideas so they know their investment won’t be for naught. Console manufacturers do this. This doesn’t have to be free; a lot of developers would pay a fair price for pre-approval. It would be cheaper than investing months of their time into an application that won’t be published.
  3. Let developers self-publish applications. Let all users manually install provisioning files so they can run a specific developer’s non-Apple-signed applications.


My First iPhone App: Lessons Learned

I recently finished my first iPhone app and submitted it to Apple to get a feel for the iPhone App Store. I didn’t want to invest a lot of time into this experiment, so I decided to add some polish to a very simple game I had already written for my own amusement, and put it out there.

I’m probably going to write a second article detailing some sales numbers (they’re practically non-existant, so I’m not sure how interesting that is going to be), but since sales never were the goal of the app, I’m going to start out with some more important things I’ve learned when writing and releasing this app.

Search

This is just something weird I have noticed. Different stores show different results for the same search term. Searching for the exact name of my app in the Swiss store shows it as the first search result, while the search position in the US store fluctuates:

Search Result Comparison

I have no idea what causes the difference.

Reviews

Most larger sites are swamped with review requests and won’t even respond to mail. Smaller sites and YouTube Channels are happy to get promo codes, but they don’t have much reach. Some sites encourage posting gaming news to their forums, which is pretty cool because it gives you quick feedback from people who actually play your games.

To my surprise1, some sites and podcasts actually request money for reviews or frontpage placement of news items. Some even take money for reviews, and offer to not release the review if it turns out to be negative. Others have written about this:

But when I find out that certain sites are using gutter tactics like selling reviews on the sly, that’s where I draw the line. I recently lost an advertiser to a competitor that offered him a review along with his advertising package – «impartial,» of course - to better promote his game.

Needless to say that this is not the kind of behaviour the iPhone app market needs. Perhaps this might help.

iTunes App Loader

Since «Release» versions of iPhone applications are signed with a specific App Store Provisioning Profile, there’s no obvious way to test them (there is, however, a non-obvious way). In fact, you can’t even be entirely sure that the application is signed properly. To get around that, you can use the Application Loader to upload apps to iTunes Connect. It seems that the Application Loader will verify the signature when uploading the app, although I haven’t tested this (signing worked fine for me). The bickbot blog explains where to find the Application Loader.

Crashes

About a day after releasing the game, I got a mail saying basically «well, you got my money, but I can’t play your app because it crashes.»

To me, this feels like getting punched in the stomach: Somebody gave you his or her money, and the app doesn’t work because you screwed up or didn’t test enough or didn’t think of some special case. They have every right to be pissed off, because you basically stole their money.

From the description of the crash, it became obvious to me that the game crashed because it ran out of memory. During beta testing, nobody had had this issue. I assumed that my app’s memory usage was well within the limits of what any iPhone should be able to handle.

So I made the boneheaded decision to ignore memory warnings; I simply assumed that my app was small enough that it would always fit into the iPhone’s available memory and never receive a memory warning.

Turns out the person who had the crash had a jailbroken phone that hadn’t been restarted in a while. Restarting solved the problem, but the other issue is the jailbreak. Jailbroken iPhones tend to have less available memory, probably mainly due to background processes that some non-Apple-approved apps can create.2

I haven’t found an easy way of testing my app for iPhones with memory issues. What I did to check my fixes was to

  1. Create a test build which allocates and retains a bunch of unused memory when the app starts
  2. Create a test build which constantly leaks memory, eventually triggering memory warnings

That should cover most situations people might actually encounter in real life.

Daniel Ericsson points out that memory warnings can also be tested by using «Hardware» -> «Simulate Memory Warning» in Simulator.app. That that doesn’t replicate the actual low-memory situation on the actual hardware, but it’s useful for testing the code triggered by memory warnings.

For the record, my game simply turns off some animations when it receives the first memory warning, releasing the images used for those animations. This seems to have fixed the problem.

2.2

Something else I discovered during beta testing is that a lot of people still use iPhone OS version 2.2. Some don’t want to risk updating a well-running phone. Another reason is that updating jailbroken phones requires quite a bit of time, and a lot of people with jailbroken phones simply won’t bother to do it.

So it’s probably a good idea to support older versions if possible.

Performance is your Number 1 Problem

I started writing this particular game even before I got accepted into the iPhone developer program, simply to get acquainted with iPhone development. It ran just fine in the simulator, but when I put it on an actual iPhone, I was able to get about two frames per second. There was no way to salvage my code; I had to rewrite the game, making entirely different assumptions about the iPhone’s performance.

There’s a saying in software engineering: premature optimization is the root of all evil. As a general rule, this may be true, but on the iPhone, you should probably optimize constantly. Otherwise, you might end up with an application you can’t possibly get to work.

Start out with a «performance prototype» simply to see whether your idea can actually work at all. Then, during development, do on-device performance tests regularly. Fix issues as soon as they come up if you don’t want to get stuck with a wonderful application you can’t get to perform acceptably.

Finally, not all «Touch OS» devices have the same processor. Some newer iPods have faster processors. Make sure to also test your app on older, slower devices and perhaps allow the app to adapt to them in some way, either by measuring performance, or by checking what specific device your app is running on. For example, some racing games show fewer opponents on slower devices. Here’s a way to detect what device your app is running on.

Memory is also your Number 1 Problem

As noted above, memory is a constant issue on the iPhone. You may be tempted to improve performance by increasing memory consumption. On desktop computers, this typically works just fine since the operating system can page out idle applications and give your app almost as much real memory as you ask for. On the iPhone, this doesn’t work. You pretty much get the amount of memory that is currently free, and if you want to use more than that, you’re shut down.

So it’s often not a good idea to fix performance issues by increasing memory consumption. As a general rule, you should probably keep memory consumption low and release stuff as soon as you can, even if it’s bad for performance. You’ll be glad you did once the iPhone grows the ability to multitask3.

Even if your app runs perfectly fine on your iPhone and your beta testers’ iPhones, chances are your actual customers will run into memory issues you did not. They will have jailbroken phones with background processes running. They will have iPhones that haven’t been restarted in weeks or months. So even if your app requires little memory and you never had any issues, it’s probably a good idea to catch low-memory warnings anyway.


  1. Yeah, it may be naïve to expect some kind of basic amount of integrity from online gaming news sites ;-) (and no, just to be clear, I did not contact Gamespot and do not think that Gamespot would ask for money in exchange for reviews; I merely linked to this article as an example of sleazy behaviour. Also, I do not think that all online gaming sites are unethical. In fact, as far as I can tell, most of them are doing a fine job) 

  2. Please note that I have nothing against people who jailbreak their phones. There are valid reasons for jailbreaking an iPhone. I don’t blame people for jailbreaking their phones, I blame myself for not making sure the app worked properly in low-memory situations (which, incidentally, helps people with non-jailbroken phones, too). Furthermore, merely jailbreaking the phone will not increase memory consumption. Certain things which are enabled by the jailbreak do, such as services like web servers, applications with background processes, running normal applications in the background, and certain changes to Springboard. 

  3. Note that I have no reason to believe that the iPhone will ever allow for multitasking, other than the fact that it seems like common sense to add the feature once the hardware can support it. 


Next →