iTunes: another tale of woe in UX

I know that pointing out errors in iTunes is a bit passé but Apple keeps releasing new versions of this thing without addressing the fundamental problems that it has as a synchronization client.

The software has to synchronize with hardware from only one manufacturer -- the same one that makes iTunes. I'll leave off complaints about the horrific, very old and utterly non-scaling UI and just regale you with a tale of a recent interaction in which I restored my phone from a backup. In that sense, it's a "user experience".

In this tale, we will see that two of the main features of the synchronization part of the iTunes software -- backup and sync -- seem to be utterly misinterpreted.

Spoiler alert: it all works out in the end, but it's mind-boggling that this is the state of Apple's main software after almost 15 years.1

10 million new iPhones were sold over the weekend. Their owners will all have the pleasure of working with this software.

Restore from backup

Me: attaches phone iTunes: Restore from backup? Me: Sure! iTunes: shows almost full iPhone There you go! Me: Thanks! That was fast! Me: Wait...my phone is empty (no apps, no music, no contacts) iTunes: blushes Yeah, about that... Me: reconnects phone iTunes: shows nearly empty iPhone What's the problem? Me: Seriously, RESTORE FROM BACKUP (select EXACT SAME backup as before) iTunes: On it! Sir, yes sir! Me: OK. Apps are back; contacts are back. No music, iTunes? What part of the word "backup" is causing difficulties here? iTunes: blushes (again) Ummm, dunno what happened there Me: Fine. It was randomly selected anyway. Me: Select random music from this playlist iTunes: Here ya go! Me: Sync iTunes: Nothing to do Me: Sync iTunes: Seriously, dude, there's nothing to do Me: SYNC iTunes: Done Me: No music on phone. Do you understand the word "sync" differently as well? You know, like how you have trouble with the word "backup"? iTunes: ... Me: notices that size of playlist exceeds capacity of iPhone Me: that's 17GB of music. For a 16GB iPhone. iTunes: Yep! Awesome, right? Me: Is that why you won't sync? iTunes: Error messages are gauche. I don't use them. Everything is intuitive. Me: Fine. Reserve space when selecting music: 1GB (don't need more extra space than that) iTunes: NP! Here's 15GB of music. Me: Wait, what? You're supposed to leave 1GB empty of the available space not the total size of the device iTunes: Math is hard. ... You do it. Me: Fine. Reserve 4.2GB? iTunes: Done. Me: Now I have a 28GB playlist. iTunes: pats self on back Me: Reserve 3.2GB ... and "delete all existing" and "replace"? Now does it work? iTunes: 9GB for you Me: tweaks settings 2 or 3 more times iTunes: 10.5GB Me: Perfect. That was totally easy. Me: Sync iTunes: On it! hums to self Me: Why are you only syncing 850 songs when the playlist has 1700 of them? iTunes: continues humming Me: Fine. wanders away iTunes: Done Me: Sync iTunes: syncing 250 more songs Me: What the hell? iTunes: Done. Me: Sync iTunes: syncs remaining songs Me: This is ridiculous iTunes: Done



  1. It has been pointed out to me that I am using this software in a somewhat archaic way: to wit, I am not allowing iTunes to synchronize all of my data to the cloud first. Had I done that, it is claimed, I would have had fewer problems. I am, however, skeptical. I think that a company that can't even get local sync working properly after 15 years has no business getting any of my data.

LESS vs. SASS: Variable semantics

This article originally appeared on earthli News and has been cross-posted here.


I've been using CSS since pretty much its inception. It's powerful but quite low-level and lacks support for DRY. So, I switched to generating CSS with LESS a while back. This has gone quite well and I've been pretty happy with it.

Recently, I was converting some older, theme stylesheets for earthli. A theme stylesheet provides no structural CSS, mostly setting text, background and border colors to let users choose the basic color set. This is a perfect candidate for LESS.

So I constructed a common stylesheet that referenced LESS variables that I would define in the theme stylesheet. Very basically, it looks like this:


| crimson.less |

@body_color: #800;
@import "theme-base";


| theme-base.less |

body
{
  background-color: @body_color;
}

This is just about the most basic use of LESS that even an amateur user could possibly imagine. I'm keeping it simple because I'd like to illustrate a subtlety to variables in LESS that tripped me up at first -- but for which I'm very thankful. I'll give you a hint: LESS treats variables as a stylesheet would, whereas SASS treats them as one would expect in a programming language.

Let's expand the theme-base.less file with some more default definitions. I'm going to define some other variables in terms of the body color so that themes don't have to explicitly set all values. Instead, a theme can set a base value and let the base stylesheet calculate derived values. If a calculated value isn't OK for a theme, the theme can set that value explicitly to override.

Let's see an example before we continue.


| theme-base.less |

@title_color: darken(@body_color, 25%);
@border_color: @title_color;

body
{
  background-color: @body_color;
}

h2
{
  color: @title_color;
  border: 1px solid @border_color;
}

You'll notice that I avoided setting a value for @body_color because I didn't want to override the value set previously in the theme. But then wouldn't it be impossible for the theme to override the values for @title_color and @border_color? We seem to have a problem here.1

I want to be able to set some values and just use defaults for everything that I don't want to override. There is a construct in SASS called !default that does exactly this. It indicates that an assignment should only take place if the variable has not yet been assigned.2 Searching around for an equivalent in LESS took me to this page, Add support for "default" variables (similar to !default in SASS) #1706. There users suggested various solutions and the original poster became ever more adamant -- "Suffice it to say that we believe we need default variable setting as we've proposed here" -- until a LESS developer waded in to state that it would be "a pointless feature in less", which seemed harsh until an example showed that he was quite right.

The clue is further down in one of the answers:

If users define overrides after then it works as if it had a default on it. [T]hat's because even in the imported file it will take the last definition in the same way as css, even if defined after usage. (Emphasis added.)

It was at this point that the lightbulb went on for me. I was thinking like a programmer where a file is processed top-down and variable values can vary depending on location in the source text. That the output of the following C# code is 12 should amaze no one.

**var** a = 1;
Console.Write(a);
a = 2;
Console.Write(a);
a = 3;

In fact, we would totally expect our IDE to indicate that the value in the final assignment is never used and can be removed. Using LESS variable semantics, though, where variables are global in scope3 and assignment are treated as they are in CSS, we would get 33 as output. Why? Because the value of the variable a has the value 3 because that's the last value assigned to it. That is, LESS has a cascading approach to variable assignment.

This is exactly as the developer from LESS said: stop fighting it and just let LESS do what it does best. Do you want default values? Define the defaults first, then define your override values. The overridden value will be used even when used for setting the value of another default value that you didn't even override.

Now let's go fix our stylesheet to use these terse semantics of LESS. Here's a first cut at a setup that feels pretty right. I put the files in the order that you would read them so that you can see the overridden values and everything makes sense again.4


| theme-variables.less |

@body_color: white;
@title_color: darken(@body_color, 25%);
@border_color: @title_color;


| crimson.less |

@import "theme-variables";
@body_color: #800;
@import "theme-base";


| theme-base.less |

body
{
  background-color: @body_color;
}

h2
{
  color: @title_color;
  border: 1px solid @border_color;
}

You can see in the example above that the required variables are all declared, then overridden and then used. From what we learned above, we know that the value of @title_color in the file theme-variables.less will use a value of #800 for @body_color because that was the last value it was assigned.

We can do better though. The example above hasn't quite embraced the power of LESS fully. Let's try again.


| theme-base.less |

@body_color: white;
@title_color: darken(@body_color, 25%);
@border_color: @title_color;

body
{
  background-color: @body_color;
}

h2
{
  color: @title_color;
  border: 1px solid @border_color;
}


| crimson.less |

@import "theme-base";
@body_color: #800;

Boom! That's all you have to do. Set up everything in your base stylesheet file. Define all variables and define them in terms of each other in as convoluted a manner as you like. The final value of each value is determined before any CSS is generated.

This final version also has the added advantage that a syntax-checking IDE like JetBrains WebStorm or PHPStorm will be able to provide perfect assistance and validity checking. That wasn't true at all for any of the previous versions, where variable declarations were in different files.

Although I was seriously considering moving away from LESS and over to SASS -- because at least they didn't leave out such a basic feature, as I had thought crossly to myself -- I'm quite happy to have learned this lesson and am more happy with LESS than ever.



  1. For those of you who already know how to fix this, stop smirking. I'm writing this post because it wasn't intuitive for me -- although now I see the utter elegance of it.

  2. I'd also seen the same concept in NAnt property tasks where you can use the now-deprecated overwrite="false" directive. For the curious, now you're supposed to use unless="${property::exists('property-name')}" instead, which is just hideous.

  3. There are exceptions, but "variables are global in LESS is a good rule of thumb". One example is that if a parameter for a mixin has the same name as a globally assigned variable, the value within that mixin is taken from the parameter rather than the global.

  4. Seriously, LESS experts, stop smirking. I'm taking a long time to get there because a programmer's intuitive understanding of how variables work is a hard habit to break. Almost there.

TrueCrypt: yet another organically grown user interface

This article originally appeared on earthli News and has been cross-posted here.


I use TrueCrypt at work to encrypt/protect the volume where I store source code for various customers. It generally works pretty seamlessly and I don't even notice that I'm working on an encrypted volume.

The other day, Windows started complaining in the Action Center that my drive needed checking because errors had been discovered. At first, I thought that it was referring to my system drive -- which is not encrypted -- and I rebooted Windows to let it do its thing.

Windows was back up and running relatively quickly and I wondered whether it had even checked the drive at all. The little flag in the Action Center was gone, though, so all was well.

My TrueCrypt drive doesn't auto-mount, though. When I mounted it a while later to do some work, the little flag popped up immediately and I realized that Windows was complaining about that drive rather than my system drive.

Windows's advice to "reboot to fix the problem" wasn't going to work because there is no way that Windows can access the TrueCrypt-encrypted drive early in the BIOS/boot process. So I went to the properties for that volume and tried to scan it using the standard system tools.

No dice. Windows claims that it can't check that volume.

Weird.

If it can't even check that volume, then where does Windows get off telling me that the volume has errors? Had Windows noticed -- after several months -- that it was incapable of checking that drive and decided to nag me about it, even though it can't offer any solutions? As a longtime Windows user, this didn't strike me as especially unlikely.

I got advice from a more savvy TrueCrypt user that it offers its own file-system check-and-repair tools. So I fired up the main window for TrueCrypt, which appeared as shown below.

image

O-K. Now how do I check my volume? Volume Tools makes sense. Click.

image

Nope. My initial intuition was wrong. How about "Tools" in the menu? Click.

image

Strike two. Some commands are repeated from the "Volume Tools" popup and there are some other things, but "Check" and "Repair" aren't here either.

How about the "Volumes" menu? Click.

image

Strike three. Again, there are a few volume-related functions, but not the ones I'm looking for. Maybe my colleague was wrong when he said that there were check/repair tools? Maybe they were dropped from the TrueCrypt software? I'm losing faith here.

Wait, I have one more idea. How about if I right-click the volume in the list?

Click.

image

There it is.

Cue relief mixed with disappointment that this is yet another user interface that is wildly inconsistent and utterly unintuitive. It doesn't have to have a groundbreaking UI, but it could at least follow some basic guidelines. A few hours of work would suffice, I think.

I ran the check, which found no errors and repaired nothing. Windows has not complained about errors since. Very reassuring.