Vincent Gable’s Blog

January 14, 2009

People Do NOT Want to Register

Filed under: Design,Security,Usability | , , ,
― Vincent Gable on January 14, 2009

Jared M. Spool writes about how removing compulsory registration from a website translated into a $300,000,000 increase in sales. (Via UI and us). The intentions behind the registration were good: make things easier for repeat customers by remembering their information. This would reward the most loyal customers, and for first-time customers registration would only be a small one-time step. But in practice, the registration was universally hated.

We were wrong about the first-time shoppers. They did mind registering. They resented having to register when they encountered the page. As one shopper told us, “I’m not here to enter into a relationship. I just want to buy something.

…Without even knowing what was involved in registration, all the users that clicked on the button did so with a sense of despair. Many vocalized how the retailer only wanted their information to pester them with marketing messages they didn’t want. Some imagined other nefarious purposes of the obvious attempt to invade privacy. (In reality, the site asked nothing during registration that it didn’t need to complete the purchase: name, shipping address, billing address, and payment information.)

Repeat customers weren’t any happier. Except for a very few who remembered their login information, most stumbled on the form. They couldn’t remember the email address or password they used. Remembering which email address they registered with was problematic – many had multiple email addresses or had changed them over the years.

When a shopper couldn’t remember the email address and password, they’d attempt at guessing what it could be multiple times. These guesses rarely succeeded. Some would eventually ask the site to send the password to their email address, which is a problem if you can’t remember which email address you initially registered with.

(Later, we did an analysis of the retailer’s database, only to discover 45% of all customers had multiple registrations in the system, some as many as 10. We also analyzed how many people requested passwords, to find out it reached about 160,000 per day. 75% of these people never tried to complete the purchase once requested.)

The form, intended to make shopping easier … just prevented sales – a lot of sales.

The $300,000,000 Fix

The designers fixed the problem simply. They took away the Register button. In its place, they put a Continue button with a simple message: “You do not need to create an account to make purchases on our site. Simply click Continue to proceed to checkout. To make your future purchases even faster, you can create an account during checkout.”

The results: The number of customers purchasing went up by 45%. The extra purchases resulted in an extra $15 million the first month. For the first year, the site saw an additional $300,000,000.

Personally, I am in complete sympathy with the test’s participants. I don’t want to have to register to do something. In fact, I’ve re-registered for ADC a few times, because I lost my login information. (I really wish I could reclaim my first ADC membership from highschool, now tied to a defunct AOL address, because the member # is one digit shorter!)

Security Implications

Unfortunately, people have good reason to be wary of registration — it puts their credit card information at risk. And we’ve all been burned by spam and junk-mail from someone who abused registration information.

The Future is Here

Modern web browsers all have some kind of auto-fill that can remember and enter shipping/billing information. This technology obsoletes the benefits of registration in the story.

There’s more that could be done to be smarter about registration. For example, not exposing it in any way unless a person has made several orders.

Of course, the smartest thing is to avoid registration, because your users hate it. Services like BugMeNot prove this.

January 13, 2009

Wireless Network Names Don’t Tell You Much

Filed under: Design,Research
― Vincent Gable on January 13, 2009

It’s been my experience that the names of wireless networks do not tell you much about where they are. I do not use wireless network names as default names for anything.

Be aware that wifi network names are sometimes offensive! as I write this, one of the visible wireless networks is “DANKNASTY BALLASAUCE” — I kid you not. But more importantly, they are mostly generic and useless: “linksys”, “netgear1”, “2WIRE985”, etc.

Before you use a wireless network name to for something, make sure there isn’t something more appropriate you could use.

January 9, 2009

Biometrics

Filed under: Design,Quotes,Research,Security | , , , ,
― Vincent Gable on January 9, 2009

Summary of an article by Bruce Schneier for The Guardian,

Biometrics can vastly improve security, especially when paired with another form of authentication such as passwords. But it’s important to understand their limitations as well as their strengths. On the strength side, biometrics are hard to forge. It’s hard to affix a fake fingerprint to your finger or make your retina look like someone else’s. Some people can mimic voices, and make-up artists can change people’s faces, but these are specialized skills.

On the other hand, biometrics are easy to steal. You leave your fingerprints everywhere you touch, your retinal scan everywhere you look. Regularly, hackers have copied the prints of officials from objects they’ve touched, and posted them on the Internet. …

Biometrics are unique identifiers, but they’re not secrets.

biometrics work best if the system can verify that the biometric came from the person at the time of verification. The biometric identification system at the gates of the CIA headquarters works because there’s a guard with a large gun making sure no one is trying to fool the system.

One more problem with biometrics: they don’t fail well. Passwords can be changed, but if someone copies your thumbprint, you’re out of luck: you can’t update your thumb. Passwords can be backed up, but if you alter your thumbprint in an accident, you’re stuck. The failures don’t have to be this spectacular: a voice print reader might not recognize someone with a sore throat…

In Why Identity and Authentication Must Remain Distinct, Steve Riley cautions,

Proper biometrics are identity only and will be accompanied, like all good identifiers, by a secret of some kind — a PIN, a private key on a smart card, or, yes, even a password.

January 7, 2009

Objective-C 1.0 Style: Don’t Name Your Enumerators “enumerator”!

Disclaimer

There is a better way to iterate over collections in Objective-C 1.0. You really should use it. It’s easier to write, easier to read, less prone to bugs, faster, and makes what I’m going to rant about here a non-issue, because you won’t have any NSEnumerator variables in your code.

Badly Named Problem

The standard iteration idiom in Objective-C 1.0 is:

NSEnumerator *enumerator = [collection objectEnumerator];
id element = nil;
while( nil != (element = [enumerator nextObject]) ) {
   ;//do stuff...
}

Unfortunately, I see otherwise steller programmers name their NSEnumerator variables “enumerator”. That’s always wrong, because it does not tell you what the enumerator enumerates. We already know that enumerator enumerates things, because it’s type is NSEnumerator, unless it’s name tells us more then that it’s hardly better then no name at all.

This is an especially amateurish practice because …

Naming an Enumerator Well is Easy!

Call it, the plural of the element variable. And if that won’t work you can always fall back on calling it collectionEnumerator.

For example, to fix:

NSEnumerator *enumerator = [input objectEnumerator];
NSString *path = nil;
while (path = [enumerator nextObject])

We should name enumerator paths or inputEnumerator. You might find “paths” to be too close to “path” in which case let the “plural form” of element be everyElement, giving everyPath.

These rules can be applied without much thought, but will improve the clarity of code.

Why enumerator is Worse Than i

Firstly, the practice of naming an the index in a for-loop i is not good. You can avoid it by renaming i to thingThatIsIndexedIndex.

But at least, for(int i = 0; i < collection.size(); i++), is concise; therefore better than a equally-poorly-named NSEnumerator.

Also, there is something to be said for the idiom you can just use collection[i] over declaring an extra element variable.

The Right Choice

Everyone agrees informative names are good, yet poorly named enumerators are everywhere (just browse Apple’s sample code!) Poorly named enumerators persist because nobody really uses an enumerator per se, they are just part of an iteration idiom. (So stop declaring them and iterate smarter). When was the last time you saw code that did anything with an enumerator besides [enumerator nextObject] in a while loop?

But bad habits matter. Don’t pick up the habit of naming something poorly when it’s easy to do the right thing.

January 4, 2009

Conway’s Law

Filed under: Design,Programming,Quotes | , , ,
― Vincent Gable on January 4, 2009

Any organization that designs a system (defined more broadly here than just information systems) will inevitably produce a design whose structure is a copy of the organization’s communication structure.

Melvin E. Conway

As Wikipedia points out, “Conway’s law was not intended as a joke .. but as a valid sociological observation. It is a consequence of the fact that two software modules A and B cannot interface correctly with each other unless the people who made A communicate with the people who made B. Thus the interface structure of a software system necessarily will show a congruence with the social structure of the organization that produced it.”

How To Beat Web Apps

Filed under: Cocoa,Design,Quotes,Usability | , , ,
― Vincent Gable on January 4, 2009

The way Apple stays ahead of the web app trend is by creating native Cocoa experiences that can’t be duplicated in web apps — both on the Mac and iPhone.

John Gruber

December 31, 2008

Mac OS X Redesign: Feedback for “Hold Keys”

Filed under: Design,MacOSX,Usability | , , , ,
― Vincent Gable on December 31, 2008

To prevent particularly bad slips (physical, not cognitive, mistakes), Apple makes certain keys hold keys. That means you have to hold them down for a while before they do their thing, unlike any other button that you just tap to use. This prevents accidentally engaging the hold keys, because a quick tap isn’t enough to trigger them. Unfortunately, it causes major problems for users. Apple could fix things by simply adding 3 words to the key-pressed-indicators they already use, and displaying it immediately.

The eject key is a hold key on MacOSX 10.4.9+. It’s a pretty bad thing to accidentally activate, because it takes several seconds to put a physical disk back into a tiny slot . By comparison the most common slips (typos), can be corrected in a split-second with 2 keystrokes(delete + the right letter). The eject key is located just above the delete key (which behaves like backspace on other computers), and right next to F12, which by default is mapped to Dashboard. Both of these keys are relatively high traffic, so it’s a sure bet that many a slipped finger will tap the eject-key. Making the eject-key a hold key prevents accidental taps, because a tap isn’t enough to trigger it.

caps lock on new keyboards is a hold key to turn on (but not off). Anything that makes caps lock harder to engage is great, since there’s no good reason to have a caps lock key anyway.

But there is a big problem with what Apple has done here. There isn’t any indication that hold keys are special. Worse, if you try to use one the way you use every other button on the keyboard, mouse, or computer — by tapping them – nothing happens. It’s like the hold keys are broken. here’s a video showing how confusing the eject key is.

One of the first things I noticed after updating Mac OS X Tiger to 10.4.9 was that my CD eject key didn’t seem to work anymore

Unfortunatly, that is a common reaction.

All hold keys should give immediate feedback when tapped, and also indicate that they need to be held down to trigger their action. Macs already flash an translucent eject indicator when the eject key’s action is performed:

Media Eject Symbol

Immediately displaying the following indicator, and pulsing the symbol when the action is triggered does everything we need:

Media Eject Symbol + 'hold key down' message

This is just a quick mock-up to get the idea across, it has a lot of flaws.

Unlike the eject symbol, the text has no drop shadow — this makes it less busy, and easier to read; but arguably unaesthetic.

The text is in all lowercase, because all words on Apple keyboards are in all lowercase. The idea is that it more closely associates the instructions with the keyboard. It’s probably a mistake, since it does not follow the capitalization rules for Mac OS X, but it made sense to me at the time.

The text also should have a stronger border, so it will show up clearly no matter what it is displayed over. And it should be bigger. And in a better font.

But hopefully this is enough to get my idea across.

December 30, 2008

Different Symptoms of Different Eyestrain

Filed under: Accessibility,Design,Usability | ,
― Vincent Gable on December 30, 2008

(Sheedy, Hayes, & Engle) found that reading with difficult environmental conditions such as upward gaze, glare, flickering light, or small text caused the participants to report symptoms of burning, irritation, and dryness.

While reading with internal problems like having to turn your eyes inward, astigmatism, and stress on the focusing lens caused the participants to report ache, strain, and headache.

Sheedy, J.E., Hayes, J., & Engle, J. (2003). Is all Asthenopia the Same? Optometry and Vision Science, 80 (11), 732-739.

Via fontblog.

December 20, 2008

“Most Windows Developers Couldn’t Care Less About Design”

Filed under: Design,Programming,Quotes | ,
― Vincent Gable on December 20, 2008

Judging by the applications I’ve used, most Windows developers couldn’t care less about design. That’s bad. What’s even worse is learning that same design carelessness has shipped in the box with every copy of Visual Studio since 2002.

See, even Jeff Atwood says it, and he’s no Mac fanboy.

December 12, 2008

One assert() You Need?

Accidently disconnected outlets in shipping Cocoa apps are legend.

Jonathan “Wolf” Rentzsch

From what I can tell assert() is slowly going the way of the goto in the programming world. Exceptions, unit-tests, and other modern software engineering practices, seem to have a better answer for testing something at runtime, and ensuring that you never enter a bad state.

But there is one case where I think you should put an assert() (and not an NSAssert()) in your code: in awakeFromNib assert() that every IBOutlet is connected.

It’s surprisingly easy to accidentally disconnect something in Interface Builder, or rename something in Xcode. I’ve done it before. More then once. assert()-ing IBOutlets has saved me a lot of debugging time.

Hard to Find In Code

An IBOutlet that is not connected is nil. Because Objective-C quietly ignores messages sent to nil, it’s very easy not to notice the problem for a while; then spend a long time debugging a side effect of the issue.

Hard to Find By Eye

A widget in a nib/xib file that is not connected will never change it’s state. But it typically it has a reasonable initial state. This makes it difficult to detect disconnected IBOutlets by eye, because things will look right until they are supposed have changed, but the eye is drawn to change, and de-emphasizes unchanging things.

Why assert()?

As Wolf says, the worst-case-scenario is that right before release you make a trivial change in Interface Builder (“We can’t ship with that window saying “Claculator”), an IBOutlet gets disconnected, and nobody notices in time.

But an assert() failing will be noticed with casual testing, and triggered if the nib is loaded at all, even if the series of interactions needed to cause the widget to change state are not performed.

An assert() is very light-weight and easy to do. It’s exactly one line of code, and you don’t have to add a unit testing framework to your project to do it. And that makes it perfect for test projects. I’m a believer in getting a feature working in a test project first, then copying it into your real product. (Honestly I don’t do it as much as I should, and I almost always kick myself for it.) It lets you test and learn without hacking-up your product. Plus, new things are often easier to try without the weight of a big code base.

Speaking of unit tests, I don’t have complete faith in them here. That’s because a disconnected IBOutlet in a shipping program is fundamentally an issue with the way the release-build is configured. So anything that’s not testing the the actual release build is not exhaustively testing for this problem. an OCUnit-test can catch a disconnected IBOutlet if it is loaded into the application. But in my experience, such tests are cumbersome. Running them involves launching your full application, and programatically manipulating it. This can take a while to run since all the UI will be displayed and animated. And you have to be careful about state since each test will be changing the state of your program.

Ultimately, assert() just seems to be optimal, in dependability and simplicity, for catching a disconnected IBOutlet.

But I suspect there’s a better way I don’t know.

How do you catch IBOutlets?

« Newer PostsOlder Posts »

Powered by WordPress