Interaction ProTip #5: The ABC of Interaction
I spent a few hours in a hospital waiting room this past weekend. It started off fine (as fine as a trip to hospitals ever are!), I got straight to the reception and checked in. The lady there advised me that there was a bit of a wait to see any medical personnel and that I should take a seat, which I duly did. But as time went by I started to get bored and agitated, not because anyone was doing anything wrong per se, but because they failed to provide me with any kind of update. Two hours later, with no updates, my head was in a pretty bleak place.
It kind of made me think of interactions in apps, bored as I was, and I formulated a little ABC acronymy thing. It goes like this: Acknowledge, Begin, Communicate.
By way of illustration let's assume we are building a widget where a user makes a simple yes/no choice which we will then send over to a server.
Acknowledge #
In most cases acknowledgment comes in one of two forms:
- Visual confirmation the user's choices. This might seem obvious, but you should make it super clear to the user what the current status of the UI is. If they make some kind of gesture or choice it should be super clear that you have registered it correctly. Apple has faced this problem recently in iOS 7.1 where some users are unclear as to whether or not their shift key is pressed. This is a classic case of users asking "did it do what I expected?" and that's what we need to avoid.
- Validate the user's choices. If you can validate the user's input quickly and easily, do it. It's better than making a round trip to the server side to just come back with errors. That said, you absolutely should validate the data on the server side every time, just do it on the client side as well if at all possible. It's faster.
In this example I simply disable the send button until an option is selected. The alternative would be to only notify the user that they need to choose an option when they press the button. The problem with that is it's annoying; it's like being sent to the naughty corner because you didn't infer the magic ritual you needed to perform.
At this point the widget doesn't actually send anything to the server side, but that comes next.
Begin #
I'm not going to spend a lot of time on this because I'd probably go down the "how to implement something" rabbit hole, and that's not what I'm focusing on here. It's the bit where you process the user's action. What's important is that you've acknowledged (and validated) the user's choice before you start acting on it. It gives us our all-important 'B', though, and I'm nothing if not committed to a tenuous acronym.
Communicate #
This is the bit I think that we overlook most often when we plan and build our interfaces. We assume that nothing will go wrong, or, if we do, that actions simply have success or fail states.
In fact, most decisions in life outside of a browser are far more nuanced. If you're helping someone and you hit a snag you probably do several things:
- Try the thing again a few times.
- Explain to the person that you're helping that something isn't quite as you expected.
- Offer to try again later, try something different, or simply give up.
First up, "trying something different" doesn't really map that well because hopefully you should know what you're supposed to be doing, so let's park that and look at the other bits in more detail.
Try again a few times #
If in our example you were posting the user's choice over to the server side you could set a relatively short timeout and, in the event of failure, attempt to send the data again several times. You wouldn't want to keep trying forever, but there's definitely something to be said for it. On mobile, where patchy connections are pretty much a given, it may introduce a little more perceived reliability to your app.
Talk to the user #
When you sit back and consider an action in detail, you will almost certainly find that there are several points of potential failure. In our example here are the immediate ones that spring to my mind:
- The user is offline.
- The user is online but the connection is patchy.
- The user is online and the server side is slow to respond or entirely unresponsive.
Now I'm not saying that you want to tell the user exactly what's going on in gory detail when you run into issues, but what you do want to do is look at these points of failure and figure out what you need to tell the user and when.
Let's teach our widget some communication skills:
You can see here when you click on the send button I drop in a swirly "I'm doing something" animation for some immediate acknowledgment. But after a few seconds of inaction from the server a timeout is triggered that tells the user that it's taking longer than expected to get a response. It's jolly British about it, too, which is a frightfully good thing.
Give the user some sensible options #
When something fails, or looks like it's going to, we can do a few things:
- Offer to store the data offline and attempt to post again later. Whether this is a suitable option is really going to depend on the nature of your app, but remembering the user's choice might provide a much better user experience.
- Offer to retry. Sometimes the user will know why something failed, and they may just want to give it another go.
- Quit and call it a day. Of course, occasionally it's just not worth the hassle and they will just want to quit. (That doesn't mean you can't store their choices and entry for future attempts.)
It's entirely your call as to what you choose to do, of course, but hopefully you can see "success" and "fail", or "let's just hope it all works out" approaches generally miss an opportunity to offer a better experience.
This is not just a developer concern #
Perhaps your gut reaction to this is that developers should be dealing with this, but I wholeheartedly disagree. The "what happens when this goes wrong?" question is something that spans UX, design and development: UX should be deciding what the process and messaging should be, designers should be ensuring that it looks and feels right, and developers should be crafting code and ensuring all eventualities are covered.
Like all interaction work, it's a team sport.