I’ve blogged before about Sensible defaults and Anticipating User’s Needs. One suspicion that the feedback I received to this article raised in me was that people are very unclear about when inferring user intention is good, and when it gets in the way. Of course, this is not easy, and thus there’s no clear-cut answer, but if you’re aware of what you are doing, you can find the right way.
Distinguish Inference from Knowledge
Just like when designing any other algorithm, there are two extremes: On one hand, you may actually know what the user is trying to do. E.g. the user chooses the Quit menu item, and everything has already been saved: You know that the user wants your app to go away. It’s straightforward to implement.
On the other hand, there are also cases where you do not know what the user wants to do. E.g. the user has chosen Quit, but has unsaved changes. Does the user want to discard all changes made? Or did the user forget to save?
What can we do in the second case? Well, for one, we can apply a heuristic. We can assume that the user doesn’t want to lose data, and just save implicitly and then quit. Any user that actually didn’t want to apply the changes she did would simply be screwed. We could assume that the user knows what she’s doing and just quit and lose all unsaved changes. But everyone makes a mistake, and computers should be forgiving. No action the user initiates should be an irreversible mistake. Heck, even my washing machine lets me pause it and add a few more socks I found behind the couch. Why shouldn’t my Mac?
Still, both are options we have. There’s also the third option that we have: Put a fat stinkin’ dialog in the user’s face. This is the equivalent of grabbing someone about to leave a store by the collar and asking him: HAVE YOU PAID YET? This may sometimes be necessary, but generally you want to be nice to your user, you don’t want to halt them in the middle of their work. Ideally, you’d just quietly do the right thing.
The thing to keep in mind here is that you simply do not know what the user intended to do. Even worse: although the user explicitly said Quit, you do not know whether you should do that. This is neither bad or good, but it is an important thing to keep in mind when you design your program: How certain are you, that what your app is doing now is what the user wants?
If you are very sure, go ahead, do it. But what if you’re not so sure? The first rule should be: Do No Harm. The developer is given care of the user’s valuable data, her work, so he should not damage it. Take our quit example from above: In most applications today, you should not just quit if there are unsaved changes: Not saving would lose whatever changes the user just made, saving could damage the previous state of the data by applying changes that were never intended to be saved.
So, should we ask?
What if the user could just re-open the document and undo these damaging changes? In that case, just saving would actually be a much better choice. Nothing is lost, and the saved undo stack in the document lets us revert any damage.
So, you see, even in a common case, which is done so frequently in every application on your computer, you should actually be asking: What do I know? How sure am I of this knowledge? Is there a heuristic that lets me do something implicitly, but doesn’t hurt if I get it wrong?
Ask the User, but Do Not Ask the User
Another thing that is often done wrong when applying heuristics, is how to handle the situation where you aren’t sure what to do. Yes, you need a decision from the user, but that does not mean you should ask. Every time you put up an alert, you interrupt the user in their work, and force them to read the alert text and make a decision. If you do this too often, the user will just get used to clicking one of the buttons, without reading. The one time they actually made a mistake, they’ll already reflexively have clicked that button and be screwed.
Or in other words: Every time you put up an alert panel, God kills a cute little anthropomorphic paperclip.
You have many options to get input from the user, an alert isn’t the only one. And by alert, I mean everything that is kind of modal, including the weird status messages with buttons iTunes shows at the top of the window in its LED display.
For example, if your application detects at startup that it was quit with a document open, should it ask the user to reopen? I say no. What should we do instead? Well, look at your application’s workflow and typical use, of course!
If your application is mainly for generating documents, like GarageBand, where you typically create a song or Podcast over a period of time, then export it to a more standard audio format and publish it in some way, the user will likely want to return to a document. In that case, just reopen what was open last.
If your application is mainly for editing documents, for working with many documents, or for polishing and revisiting various documents, you’ll want to provide a “recent items” list instead. You can just use the built-in system menu, or you can additionally bring up a welcome window whenever no documents are open, showing recent items, templates for new files and an “open” button, like it’s done in Keynote or Xcode.
And if your application is one of those single-window monsters, for managing sufficiently distinct sets of items in a central database, you can put a “recent items” section in your sidebar. The user gets the main window, and has quick and obvious access to their most recently used item, without you loading a potentially huge item the user is not that likely to use.
Yes, I’m really saying that not asking the user, not doing anything, is OK sometimes. Your app doesn’t know with enough certainty what to do. You don’t want it to annoy the user. However, if you can infer a reasonably common case, you can still design your application to support the user in that task by making sure that, at this moment, the controls to achieve this common task (e.g. grabbing the most recent file) are within easy reach.
Also, sometimes an action is so nonsensical that you can be sure the user was trying to do something else. Instead of just telling the user “No can do”, your app can infer what they might have wanted to do, and offer to do that instead. You’re putting up an alert anyway, so why not put something useful in it?
You are not the typical user
When evaluating how certain you are about the user’s intents, also keep in mind that you are someone involved in application development. The way you use and understand the application goes much deeper than that of your users. You may know more about kerning, anchored selections and grammar-checking algorithms, while the users of your text editor may know more about particle physics or elaborate stitching, or whatever topic they are writing about when they use your text editor. A novelist has different needs than someone who mainly writes correspondence, who has again different needs from someone writing a technical manual.
So, when you infer that “everybody hand-picks their photos off the camera”, keep in mind that that may not at all be true. Someone taking a large amount of photos on a holiday to Lucerne, Switzerland, will probably want to quickly empty the memory card of the camera by transferring all photos to their Mac, and then quickly head out again with a fresh card, to enjoy the place more. They will want to just plug it in and have it import all while they take a shower.
On the other hand, a photographer on a scheduled outdoor shoot may be looking over each image anyway, to see whether he got the coverage he wanted, or whether he has to keep going to get the right picture because of a pedestrian in the background who was picking his nose at just the wrong moment, or a smudgy fingerprint on the lens that didn’t show up on the small camera screen.
So, how do I find out whether I’m right? Although there is no patented recipe, there are simple checks you can perform right away: Get a second opinion. Even if you just talk to a colleague, chances are that they use the app differently, and will spot an additional flaw in your thinking. You can give a test build to a friend and use them as your guinea pig. Ask your favorite user that e-mailed you with a “thanks for coding this” letter, how they would achieve a task that involves your new inference. Whatever. Of course, none of these people constitute a representative sample, but at least you’ll get additional data points to ponder.
And if you’re facing a big decision, you can always try more formal usability tests. But every little bit helps you gain experience, make better decisions, and discover those novel use cases you never considered.
But isn’t this inconsistent?
So you’ve tested something on your users and found that the system’s standard behavior doesn’t work. You’ve found a different solution, but now you’re wondering about consistency: everyone else on the Mac does it one way. Should you implement things differently?
The first thing you have to ask yourself is: What if a user forgets my app behaves differently? If they’ll lose data if they mix up the way your app and other apps they use work, you need to work harder. If it’s harmless … ? Well, you’ve done research to back it up, right? Tested it on a few friends, maybe even done a public beta? If you have a good reason and research to support your point that this behavior is better, then do it.
The number of beings doing something doesn’t mean it’s the best thing to do. Hey, there’s millions of flies eating doggy poo, still we humans don’t eat it…