Indie Life

There are 13 entries in this Category.

Myopic version-control islands


Being a programmer, I use version control software a lot. A while ago, there was a great upsurge in such software. I suppose it started with Versions and Cornerstone, then continued with Git clients like Tower, Github and SourceTree.

Yet none of them really innovated on their command-line brethren. This may seem like an odd desire, but there are areas where GUI clients can improve on the command-line clients backing them.

Support the user’s workflow

In one talk at NSConference, Aral Balkan once said that “your UI shouldn’t look as if your database had just thrown up all over it”. This is what I’m reminded of when I look at SourceTree.

It feels like someone took a window and just threw in a pushbutton for every action, a text field for the commit message and a checkbox for every option. It presents me all of Git at once. It overwhelms not only me, but also my screen space, as it usually shows much more on the screen than I need at any single time, but since all of it has to be visible, it is all too small to be comfortably used.

All version control software needs to become more aware of context, of “what is it time for now”. Give the user a screen display that only shows things relevant to the current operation.

The File List

The file list is not just useful for when you want to commit a change. It can help with code navigation: I’m in a big project, I’ve edited a few files, I’ve viewed many more. I need to get back to that spot I started my change in after implementing some needed subroutines and their tests. The recents list in Xcode won’t help me there, too many files I came past on my search for the right spot, some in the main tab, some in multi-file search. But my VCS knows which files I just touched.

I just go into the VCS GUI client, to the list of changed files, and there are the 5 out of 50 files I actually changed. And now that I see these 5 filenames, I can recognize what the colleague named that file. I’ve quickly found it.

Why don’t more VCS GUIs support code navigation? Let me search. Let me select. Heck, if you wanted to get really fancy you could show me the groups in the Xcode project that my files belong to. Analyze, correlate.

Peripheral Vision

The one thing all GUIs for version control systems provide these days is what I’d call “peripheral vision”: They show a constant list of files in your repository and show which ones have changed, live.

You don’t have to actively call git status. Whenever a file changes, it shows up.

By having these updates show up on their own accord, I can be warned of external influences automatically. SmartSVN, for example, shows both the local and remote state of a file. So if a colleague modifies the Xcode project file on the server that I’m currently editing locally, I immediately see in my peripheral vision that I have a pending conflict.

Each Version Control System an Island

Most of the version control GUIs I’ve mentioned ignore one important fact of most peoples’ work with version control: Sure, it is useful for single developers as unlimited undo, but most of the time it is used in collaborative environments.

If I’m collaborating with someone, isn’t the most important thing here to keep me abreast of what other developers are doing? Why do all the GUIs except SmartSVN with its horrible non-native Java grab-bag UI focus so much on making me see my working copy that is right here in front of me, and then come up surprised when something on the server changes and drop me into an external diff client without any hand-holding?

Apart from showing remote status, why don’t they keep me informed of incoming changes? Why does Cornerstone only let me view the log history of individual files or folders, but doesn’t constantly keep the list of commits in my peripheral vision? Why does no client offer to show me a notification whenever a new push happens on the server?

They just don’t Learn from History

The commit history also seems to be an afterthought to most VCS GUI developers. The only human-curated part of the entire commit metadata is usually hidden on separate tabs, or at best fighting for space with the file list and lots of other UI. File names are short. Commit messages are long. Why should those two lists be forced to be the same width?

In Versions, the commit list can only be read. I can see the changes in it and the message, but can’t select a commit in the list to roll back to that commit, or branch off from it. This is one of the basic tenets of UI design: Don’t have the user type in something the program already knows. The commit hash is right there in front of me on the screen, why do I have to type it in to check out?

Moreover, the list of commits in Versions is not scannable. There are barely noticeable color differences in the date, name and commit message, and they’re too close together and separated by lines.

Ever wonder why Finder uses alternating background colors to distinguish table rows? Because it’s easier to scan: Lines are read by the mind as glyphs, additional information to be processed, whereas the “line” where two different-colored surfaces meet are just accepted as a gap between things.

That’s why so many lists use columns. That way, if you’re looking for a commit from a particular colleague, you just scan down that column, able to completely ignore the commit messages.

The User doesn’t make Mistakes

Users don’t make mistakes. Bad GUI just leads them down the wrong path. When a user makes a mistake, be forgiving.

A contradiction? Yes. While most VCSes already under the hood have the policy of never losing data, GUIs can improve on that. Undo on text fields. Showing a big warning banner across the window when the user is on a detached head, which the user can see even if the window is half-hidden behind Xcode. Offering to stash changes for the user if they’re switching branches and have unsaved changes.

If the user selects three “unknown” (aka new) files and asks you to commit them, don’t just abort with Git’s standard error saying that they aren’t under version control! Try to anticipate what the user wanted. Show a window with a list of the offending files and offer to automatically stage them (with checkboxes next to them to turn off ones they might not have wanted to commit).

If a user tries to commit a binary file that has its executable bit set, maybe ask for confirmation in case they’re accidentally checking in the build products, and offer to add the file or one of its enclosing folders to the .gitignore file.

If the user tries to amend a commit, be smart and warn them from changing history that’s already been pushed. But don’t warn them needlessly. Can you check if any remote is ahead of this commit to detect whether the user has already pushed the commit to be rewritten? If not, it’s safe, just let them do it.

Remote Possibility of Supporting a Workflow

I’ve mentioned how we need to try to support the user’s workflow more and how the server is under-served. This also applies to setup. One of SourceTree’s standout features is that it lets you not only enter your Github or Bitbucket URL, but also shows you lists of your remote repositories.

You can set a default folder where your programming stuff goes, and then just select one of your remote repositories and click “clone”, and poof, it checks it out, adds a bookmark for it, and opens it in a window and you’re good to go. Heck, Git Tower even lets you specify the address of an image file in your repository to represent it in the list for quicker scanning.

Why has no VCS GUI added a Coda-style project list and automatically looks for project files and their application icons in a checkout to pre-populate the icon?

Re-open the repositories (yes, users may want to open several at once, deal with it!) the user had open when your app was quit. And for heaven’s sake, why are there VCS developers who don’t know how to make their application accept a folder via drag & drop on its application icon in Finder or the dock so I can quickly open a working copy that’s right there in front of me without having to wait for an open panel to open up?

Promise to be Better

I’m sorry, this has turned into a rant there. But the fact is, there are so many VCS applications, yet most simply expose the commands of their command line equivalents. Why do so few protect me from commonly made mistakes and focus on what me and my colleagues want to achieve instead and support us in that?

How can products connected to servers be so asocial?

WWDC First-timer tips

Packing for my 8th WWDC, I thought I’d note down a few tips for WWDC first-timers and USA/San Francisco first-timers, particularly ones from Germany or Europe, to take away the scariness:

  • Apple have Moscone open the Sunday before WWDC, pretty much all day (I think last time it was 7 to 7). If you’re there on that day, go and get your badge ahead of time. It’s much less hassle, whether you plan to queue for the keynote or just amble in later for the State of the Union after a leisurely breakfast. Be sure to bring some sort of ID, which they will want to see at pick-up.

    Also, later during the week (Wednesday or Thursday), you need ID to get the little wristband for the WWDC bash (the party in Yerba Buena Gardens where they serve free beer/wine/food and have a band playing). You need your badge to get in, but the wristband is how they see that you’re old enough to drink. If you find yourself in the corridors during a session, that’s a good time to beat the rush and get that wristband.

  • Lock down your devices. Turn on passcode lock, screen lock after inactivity, turn off auto-login etc. so if you lose them people can’t get at your data that easily. Make a backup before you leave (preferentially a full SuperDuper clone). Also turn off any file sharing and screen sharing services you may have activated (it’s fun to drop a 10GB file in someone’s dropbox during a boring session…). WWDC attendees are generally nice and well-behaved, but there’s no reason to tempt fate. Also, set up a unique lock screen image and put on a sticker with your company logo, name, or a Gelaskin or put it in a case so you can tell it from the dozen or so other devices around you during the conference.
  • Apple provides breakfast in the morning (croissants, bagels, coffee, tea, soft drinks, that sort of stuff) and boxed lunch around noon. The breakfast is fine, the boxed lunches are not horrible, but as you are in San Francisco, a city with great food, restaurants and culture, it seems like a shame to settle for boxed lunch unless you really don’t have time for a break.

    Often people just head out in small groups to the Westfield mall food court or other places nearby and have lunch there. You get a little bit of exercise, fresh, warm food (everything from Asian tofu to Mexican to real US-American hamburgers at the diner at the corner – and that’s just near Moscone, in the evenings you can head to Japantown or Chinatown for even greater food choices), and most importantly: Sunlight.

    If you choose to go with the boxed lunch anyway head across the street into Yerba Buena gardens (there’s a stairway to an overpass at the side of the Metreon). It’s much nicer to sit on the grass in the warm sun than in the cold lunch hall of Moscone.

  • A lot of communication happens via Twitter, Glassboard, and the likes. (The WWDC app and web site have the schedule, but no social networking) While you can usually wing it and just come up for breaths of Twitter or E-Mail in Moscone and your hotel Wifi, some people get a pre-paid SIM card and data package for their iPhone, so they can also check for messages at the various party venues (with 5000 nerds in Yerba Buena guardens during the bash, forget about even cell-phone reception at that time and just enjoy the music and conversations).

    People usually go for AT&T’s GoPhone cards. I heard rumors T-Mobile hads recently upgraded most of San Francisco’s city centre in a way that also works with European iPhone models, however I’ve also heard from people who had no reception at all. Whatever is true, you’ll only have EDGE reception outside of San Francisco with T-Mobile and a European iPhone (their 3G is on a frequency European phones don’t do), so keep that in mind when choosing a card. (planning to see the Apple campus in Cupertino?) I’ve bought a data SIM in the past for WWDC, but haven’t decided yet for this year.

  • If you decide to queue for the keynote, keep in mind that seats at the front are generally reserved for the press, team members and VIPs, and there are only a few front-line seats at the sides. The likelihood of you getting a good seat is low. About halfway back, there are screens, so if you end up near those, it’s often better to move back a few rows to at least be able to see what’s happening onstage on the screens. Best see queueing as an opportunity to meet and chat with fellow queuers, and get some swag from companies who know the queue is there and send their people.

    Here’s how queueing generally works: You get to Moscone, and the queue is already once around the block. Find the end and queue up, chat to the people there for a few hours. 3rd-party companies will arrive and start handing out stuff (in previous years there were people handing out issues of MacTech, T-Shirts from Fastmac, stickers, invitations to Nokia parties…).

    Near the end of the wait, Moscone’s front doors will open and people will be let into the bottom floor, where they will queue in the corridors in front of the elevators. This will cause the queue to appear shorter than it actually is. Then Apple will start opening floor after floor, so there will be a queue on each floor *and* around Moscone. On the top floor, there will probably be bagels and coffee for the people waiting there so you can have a quick snack).

    Then, shortly before the keynote starts, they will let people into Presidio, the big hall on the top floor where the keynote takes place. Once that is full, the remaining people will be redirected into ‘overflow rooms on the second floor, where they will see the keynote on big screens. As a first-timer, I recommend you try the whole keynote queueing thing just for the atmosphere, but I haven’t done it in quite a while and instead had a nice breakfast with friends watching bootleg streams and/or live text feeds.

  • In general, the value of the conference is in the people you meet. Since all the sessions become available for download after the conference (and to all appearances, this year even during the conference, though nobody knows in what way and with what delay), if you have the choice between attending a session or talking to a person, pick the latter. The only exception might be the lunchtime talks, which are usually held by people from outside Apple, sometimes even celebrities, and in the past weren’t recorded. If you care for one of those, you’ll be queueing.

    To be able to quickly connect with people, it helps to have business cards that you can give to them (Moo mini cards are very cool for this, but really, a few prepared slips of paper with your Twitter handle or web site address on them work just fine). Some people also have some stickers printed. Again, Moo makes stickerbooks that are nice and small and can contain different motives, or otherwise you can also get nicer, bigger stickers from Sticker Mule. And some people take along adhesive paper and use that to write their Twitter handle on their badge in an empty spot. I’ve also seen people use marker to do this, but I’m reluctant to irreversibly modify my badge.

    In general, try to hang out in the hallways and find interesting conversations going on and try to politely wiggle your way in. In general, that’s what you’re expected to do. Also, if you are part of such a conversation and you see someone slinking about the periphery, open up the circle and let them in. There are some really smart, really interesting, and really shy people in this community, and it would be your loss to cut them out.

    In a similar vein, don’t just go home and stay at the hotel when there are no sessions to attend. Find a party (there’s a 3rd party WWDC Party List app every year) and go there and meet people, or just look for people that look like they’re WWDC attendees in the pubs and diners around WWDC and try to hang out. That’s the best way to get something out of WWDC.

  • Go to Stump The Experts, which is a weird, skewed, unbalanced ‘Apple quiz show’ where people from the audience prepare questions and former and current Apple employees on the stage try to answer them. It’s fun, it’s irreverent. You can win a T-Shirt and other swag (often useless, or at best of nostalgic value for Apple historians). But keep in mind that anything you can look up on the web or in Apple’s internal support databases is easy pickings for these people. And if you prepare a question, you better have the answer. Prepare some fun questions at home, drop them off before the show, and see if they pick yours.
  • The labs are a great resource. You can walk up to the desk and make a short-term appointment with Apple employees to ask them questions. It is like a DTS incident, just with faster back-and-forth, and with the chance of you just showing them your app and having them poke around in it, without having to send Apple the entire source code. Also, Apple employees know the innards of their code, so if you get unexpected behavior from an API, they might know what internal call to set a breakpoint on to find out what’s causing your problems.

    It’s your right as an attendee to queue up and try to get time with an employee, but please do everyone a favor and come prepared. And don’t ask basic questions just because you’re too lazy to finish reading Aaron Hillegass’ book on Cocoa or get a basic idea of how Mac/iOS programming works. Do your research, prepare your code, try to get a simple test app that reproduces the problem, phrase the actual question you’re asking beforehand.

  • Bring a Mac laptop (+ USB/Ethernet adapter if it’s a MacBook Air) and an external hard disk. That way, you can download and install any new OS, developer tools, iTunes and Firmware versions Apple includes, but don’t have to nuke your internal install. If you’re an iOS developer, also bring a spare iOS device so you can install a new OS without the risk of bricking your only cell phone.
  • There’s a lot of fun things you can do in SF, particularly if you’re there a week early or afterwards. A few suggestions: Ride the cable car, see Alcatraz (reserve a week or 2 in advance on their web site!), rent a bike and bike the Golden Gate Bridge, go to the comics shop near Market and Kearny, have hot dogs on Union Square, buy iTunes gift cards and open a separate US iTunes account.

    If you’re a student, the HI Downtown is a cheap, nice youth hostel to stay at and meet many other WWDC students, if you get one of the renovated rooms with in-room shower/bathroom. But lock away your valuables (they sell padlocks for the lockers).

  • San Francisco has unusual weather: During the days, it is hot and often sunny, but also often cloudy. So take along sunscreen and apply it when you’re outside. Even sun behind the clouds can burn you, and you don’t want to be one of the red WWDC-first-time-lobsters. In the mornings and evenings, SF gets really cold. So also bring a sweater.

    In general, I recommend long slacks, not shorts. Especially since the AC inside Moscone usually cools it down quite a lot (particularly inside the lunch hall where the labs and the Apple swag store are). Also, of course, have a raincoat and keep an eye on the weather report, but that’s just common traveling sense. The cold goes double if you’re planning to queue for the keynote. It gets cold in the mornings when the fog rolls in. Hoodie and jacket.

  • This is a flight to the USA. It will take time, so get yourself in a zen mood. This begins at check-in, where you have to be 2 hours early and go through US customs, with all the security theatre that entails, including taking your shoes and maybe belt off when directed to do so.

    Also, remember to drink any water and other liquids you have *before* you enter security, and not to have a pocket knife in your carry-on luggage (you can stash stuff like that in your checked luggage, that’s fine). Just walk through, smile at any jokes the customs people make, but don’t joke yourself. On the other side, keep in mind that while they’ll happily sell you new liquids, you won’t be able to take those through any additional customs checks if you change planes unless you can get at your checked luggage and put it in there.

  • Make sure your passport is current even a while after your return flight, and that you have a Visa, or if you’re a European, that you’ve filled out the ESTA form on-line so you can go under the Visa Waiver Program. Also, make sure you have planned your whole trip before you fly. I once bought a flight to the US, and a return flight from Canada, and thought I’d take the Greyhound in between. They pulled us out and asked us a lot of additional questions. So make sure you have a continuous plan how to get into and back out of the US, and they’ll be happy.
  • Print out all information you’ll need on the flight. You won’t have Wifi there, and data roaming costs an arm and a leg, so you’ll have those off. Have a printout of: Your full destination address in the US (i.e. the hotel you’ll be staying at – customs will want this), BART or other bus/train stop for it, and if you arrive late in the evening where not many trains go, the train times. Also your ESTA number, if applicable.

    Printouts of Google Maps are useful here, or get the neat OffMaps 2 app and download the relevant maps to your iPhone before you leave. However, keep in mind that you’ll have to save battery if all that info is on your phone. I’m paranoid enough to want to have a printout anyway, and a copy on every Mac and iDevice I have with me.

  • Once you arrive, you will want to get from the airport outside town into San Francisco proper. For this, you can use BART, the San Francisco subway. This works like many other subways in the world: You have tickets with a magnetic strip, which you top up with a certain amount of money. There are vending machines for those right at the San Francisco BART station.

    The trip into SF, last I did it, was about $10, so I usually put $20 on it so I have everything set for the way back. You just pop the card into the front of the turnstiles, it comes out at the top, you grab it and walk through. Same when you exit the destination BART station, where it will then subtract the charge for this trip and print it on the card. You can re-use this card on your next visit to SF, or look up the exact charge and make sure there’s nothing left on it once you return to SF Airport.

  • Changing money from foreign currency is generally a better deal in the destination country than in the country you’re coming from. So get enough cash for the train/cab fare from the airport, but withdraw the majority of the money from a cash machine at a local bank when you arrive in San Francisco. You may want to give your bank a heads-up you’ll be in SF, though. Some banks are suspicious about foreign withdrawals and might deactivate your credit card for fear of theft or fraud if they see there’s a charge on your card from a foreign country. Particularly since, most US banks don’t use chip-and-PIN, but only use the magnetic strip, which can be copied to a blank card easily.
  • Once you arrive in SF, make sure you have a credit card. The US are a very credit-card centric country to begin with, and hotels get your credit card number on check-in so any charges you incur (mini bar, room service, breakfast, TV sets you throw out the window during your rockstar party) can be charged to your credit card. Often they will ‘put a hold on’ the price of your stay on the card as well. Anyway, even if your company pays for the stay, they will want to see a credit card for the rest.
  • There are crazy people in San Francisco. Mostly the good kind ;-), but also others. While many cities in Germany have their mentally ill citizens safely under the care of the social system, you will see the odd homeless mentally ill person walking through the street, or sitting on the sidewalk panhandling, or urinating somewhere against a building. They’re usually harmless, though they take some getting used to. Your best bet as a newbie is probably to just ignore them and head on to your destination. If you’re curious, I recommend you solicit the opinion of a US-American at the conference. It might not be the most fashionable conversation-starter, but it is one.

    Also, while San Francisco is a safe city, there are two things to keep in mind: First, every big city has pickpockets, be it Munich, Prague or SF. Put your valuables in inside pockets with zippers. In your bag with a flap over it (and your hand on it for safety) or in a fanny pack is not sufficient, particulalry in crowds where you get jostled and will not notice. Second, stay out of the Tenderloin district (roughly the start of Eddie Street and a few blocks behind it). It’s where people get mugged and attacked.

  • Bring chargers, plug adapters and a power strip. North America has its own electrical plugs, giving you 110 Volts. Most power supplies these days can take both 110V or 220V (all Apple chargers do, for instance), but you’ll still need the right plug adapter. Also, many hotel rooms have few power outlets, so a good trick is to use a plug adapter to attach a German (or whatever you use) power strip to the outlet there, then plug all your chargers into that.

    At WWDC, Apple set up power strips in most of the rooms and some hallways. However, you’d do well to pack the cable that comes with your MacBook’s power supply, not the little duck-head. That way, you get a smaller footprint on the plug, and aren’t covering up valuable outlets for others in the audience with your power brick.

    BTW, the plug embedded in the duck-heads (and also the little corner piece at the end of the cable) of Apple’s power supplies is a standard plug, a IEC 60320-1 C7 coupler, which you can likely buy at many electronics stores. It won’t look as nice without the white corner and little “hook” Apple has on it, but it’sa cheap way to get a small, US-compatible plug without needing a second plug adapter when you’re on the go while your devices are charging in the hotel.

  • A few tips for the flight there, which for many of us is 10 hours or worse: Bring snacks (avoid meat, fruit or dairy, you might run afoul of import restrictions), make sure you have a current checkout of your Git repositories on your Mac so you can work if you want to, and load as many podcasts, audiobooks, Kindle/iBooks books, Comixology comics, movies or TV episodes as you can on all your fully-charged devices (Remember, you can fit more episodes on it if they’re SD).

    If your airline provides power to the seat, get a Magsafe to Airline power adapter, if needed, otherwise get an external battery so you can avoid running down the internal battery during the flight. Many airlines these days have in-flight entertainment and even show fairly recent movies, but it’s always nice to have your own preferred selection with you, for when you get bored. Also, the headphones they hand out are horrible and un-shielded, so you might want to get an airline-to-headphone adapter to use your own in-ears (two mono jack connectors to one stereo).

    Also keep in mind that an airplane seat is still a public place. Only watch movies that won’t traumatise a little kid next to you. I’d draw the line at CSI. That’s gory but still OK, but I won’t be watching Hannibal or Spartacus on the plain, that’d be rude.

    You will have Jetlag, so don’t arrive too close to the start of the conference, leave a few days to adjust. What helps me is to have a flight that arrives in the evening (local time). Then I just force myself to stay awake during the flight (most planes serve food on the source country’s schedule, so switching to destination time right away rarely works), and am then sufficiently tired to sleep through the night and not wake up too early. If you are tired, don’t go to sleep in the afternoon, that’s the worst thing you can do when you’re jetlagged, you’ll just be awake all night.

  • Shoes and clothes are comparatively cheap in the US (at least compared to Germany). Now don’t go overboard, but if you wanted to buy new shoes anyway, or new jeans, this is a good opportunity to pack a little lighter or take along those ratty old shoes, then buy new stuff in SF and throw the old stuff away there. Just look up what your size is equivalent to in the US system beforehand.

    The same works for electronics, but there you have to be a tad more careful: Make sure it comes with a power supply that can take 220V and that you can buy a version of any power cables with the correct plug later at home, and avoid equipment that uses radio of some sort, as certain frequencies in one country are used for e.g. the police band that are used for e.g. Wifi in another. You could get fined for causing interference, or customs could confiscate a device because it doesn’t have the required certifications for use in your country (e.g. the ‘CE’ logo).

    Also, photo cameras require knowledge on your part, as many of them are manufactured in European and US versions which then don’t do PAL and only do NTSC for TV output. On top of that, many manufacturers use different names for the wto versions, so it’s harder for tourists to find the cheaper equivalent.

    And of course, keep in mind that getting electronics from the US serviced in Europe may be difficult, and warranty times may be shorter. And ensure you’re familiar with customs regulations and maximum weights for airline luggage before you make a bigger purchase.

    Finally, buying MacBooks is a bit hard to do (unless you order in advance and get it delivered to a friend in the US) if you don’t want a stock configuration with a US keyboard (which most programmers prefer anyway).

  • Last, one plea: If you’re tired, walk out of the session, find a bean bag on the top floor and have a nap. It is disrespectful to the speaker and prevents other attendees from understanding him if you fall asleep and start snoring. And while that might sound funny, so far I’ve had an attendee do that in a session every year. It’s understandable, the rooms are dark, you’re jetlagged, you’ve been partying late and are maybe hung over. But if you notice your eyes are flagging, walk out. It’s less of an annoyance than being that snoring guy spoiling it for everyone.

Note: All of the things I say Apple does here are from previous experience. Apple changes and adjusts WWDC every year (e.g. sometimes food was served at the end of the first day on the second floor), so don’t bet on it being identical. There might be less food, the food might be fantastic, it may be in-edible, it may be Soylent Green. Who knows.

iPhone 4 3G prepaid data plan for WWDC


Update 2015: This year I went with a T-Mobile card. They have a data-only card that is $13 for 1GB. I had to keep prodding them “don’t you have anything smaller” for a while to get them to stop offering me 3x as expensive plans with phone service, but beyond that you can now just go in and ask for “a data card for my iPhone for about 1 week”. Coverage is fine inside SF proper, I haven’t tried it in the valley yet, Their 4G frequencies (that’s a bit under LTE) are in the proper range for European phones.
Update 2014: AT&T still has GoPhone plans. They’re now slightly different in size and cost: There’s two plans, one $40 (500MB included, for every additional 100MB you have to top it up with an additional $5) and $60 (2.5GB included, each 1GB is a $10 top-up). You just go there, tell them what phone you have and which plan you want, pay, and Roberta’s your aunt. No APN adjustments or cutting down cards needed.
Note: There’s also T-Mobile plans, apparently, but depending on what iPhone model you have (e.g. the European one) you may not get reception in some areas because e.g. the European iPhone 5 doesn’t support the frequency that T-Mobile US broadcasts on, or T-Mobile doesn’t have coverage in that area outside the Bay Area. Leave a comment if you know details or have personal experiences.
I’ll leave the remainder of the old article here for the links and out of historical interest.

So, you’re going to WWDC and you want to have data on your iPhone 4. What to do?

  • Go to an AT&T store, and tell them you want one of their GoPhone pre-paid plans (Type in an SF ZIP code, e.g. 94133, to get to the actual page) There are two monthly (i.e. 1 month, pay again if you need another month) plans that you can get that allow data: the $25 and the $50 monthly plan. You’ll also need a data package – they offer 50MB ($5), 200MB ($15) or 1GB ($25). They will want to see some form of ID, make sure you have it.
  • Do not tell them it’s for an iPhone. If your conscience permits, say you don’t know what phone it is, you’re getting a hand-me-down from a friend later in the day, or it’s for an Android phone, or whatever. They will warn you it won’t work for an iPhone. Disclaimer: AT&T give no refunds, so if you buy the card and it really doesn’t work, it’s on your own head if that should be true one day.
  • They will give you an orange, regular-size SIM. Get a ruler, a soft pencil (HB will do), and a pair of scissors. Grab this fantastic template (the PDF link is broken, grab the JPEG that you can click to zoom in and print at 110%): My iPhone iPad blog: Convert SIM to micro-SIM. Then mark the lines on your SIM card with the pencil and the ruler and cut them using the scissors. It’s fairly easy, the chip has gotten smaller with the newer SIM cards. Don’t cut the chip! Again, if you break your card doing this, that’s your problem.

  • If you put in the card now (you’ll need a paperclip or so to open the SIM tray), it should already be recognized. I haven’t actually verified it myself, but the site above says that internet won’t work (and that’s what the shop guy says as well). So now you’ll have to point your iPhone’s browser at a special web site and create the proper APN settings file for it and activate that. You’ll need hotel Wi-Fi or so to do that part. Alternately, you can use the iPhone configuration tool from Apple and create a .mobileconfig file with the APN wap.cingular, APN user name and password CINGULAR1.

Once I did that, it worked fine for me. Again, I make no warranties. If you break the card, nuke your credit, fry your iPhone or get sued by Lodsys for doing this, that’s your own risk.

From Project to Product

Snapshot from theatre play Herzmuendung

Many new developers wonder: Where do I start making a real product that I can live off? So I thought I’d share my thoughts on this.

How to start?

The first thing you need is an idea.

The best way is to take a problem you have and try to solve it with a program. For example, in my theatre group, we used to use a CD player backstage to play the different songs and sounds we needed for the play. We just burned them all on a CD, and someone sat in the dark with a tiny flashlight and a scrap of paper listing the cues and associated track numbers. So I wrote an application for this.

It was a great success. Not because nobody ever had the idea, or because it had any high-tech features. It was just a list of sound files that got played back, with keyboard shortcuts. However, I knew where it would be used: Backstage, in darkness, with an open door to the stage. You don’t have light back there because then the audience could see all the actors of the characters that have supposedly been killed sitting there. So, you don’t do complex UI, you make sure everything is triggered by keys that can be found in a tactile fashion. You make sure all the graphics are dark, and the menu bar doesn’t brightly light up everything. You remind people at the beginning to turn down the backlight, and you tape off the Apple logo on the back of the screen.

I knew this because all the situations and problems were deeply ingrained in me, because I was familiar with the problem domain.

The second-best way is to solve a problem you see somewhere else. You may not have it yourself, but you’re close enough to know the workflow, and see the spots that can be improved. As an example, for quite a while, the US used to perform online banking by having actual humans go through the database of online money transfers, copying the information onto paper cheques, and then air-mailing whole bags of them off to whatever bank the transfers were for. That’s inefficient! Certainly that can be fixed by throwing some technology at it? Surely I can create a system that interfaces with the bank computer, then converts and transfers them to other banks?

Maybe. But maybe, this was due to US laws requiring a paper trail for money transfers. There are always surprises hidden in workflows. Not just outdated laws, but also safety regulations. As an outsider, I do not know of these. So, since I’m not inside the problem domain, I have to make sure I have an inside person who can give me the reasons for everything. There’s nothing worse than spending a year designing a perfect product whose base assumptions make it unusable in practice. Or worse, illegal.

The most comfortable way is if someone hires you to create a program for them: They know their problem domain, they have ideas for solutions, the program practically has already been designed, right? With an existing design, it is easy to forget that I am the engineer, I am the systems architect. The person that hired me probably hired me because I can do things that person hasn’t been trained to do (then again, they understand a problem domain I have no clue about, so it’s not as if they’re stupid). They have probably tried to design a program the way they think would be easiest to do. But they’re not programmers. What may look easy to them might actually be incredibly complicated, or might be aiming too low.

It is my job to “translate” their requests into a program, to find out what they really need. To achieve this, it helps to have close contact to potential users and find out how they work every day. Again, like we did in the previous approach.

The most difficult way to start with a program is to do something you always wanted to do. Take the theatre as an example again: Some roles in theatre are challenging to play, but they’re not particularly interesting to watch. Others are pretty boring and easy to play, but are most important to the audience, be it because they drive the plot, or provide some much-needed comic relief at a central point of the play, heightening the impact of the final dramatic scene. Similarly, coloraturas are amazingly fun to sing, you really get to exercise your vocal chords and breathing apparatus, but all that up and down, while technically impressive, doesn’t stay in memory as much as a simple, catchy melody.

If one of the three approaches above can be combined with this fourth option, that is a gift from heaven. But otherwise, you owe it to yourself to investigate whether there is any need for whatever idea you always wanted to realize. But again, translate from what people tell you. Henry Ford is famously claimed to have said

If I’d asked people what they wanted, they would have asked for faster horses

Similarly, the first GUIs were considered a fancy waste of CPU cycles. The iPhone was seen as useless, as existing phones already made perfectly fine calls.

The people asked back then didn’t know how not having to memorize cryptic commands would free brain power for the tasks that really count, how having a more physical display would improve comprehension of the onscreen data. How direct touch manipulation, drag and drop would speed up learning the user interface by leveraging existing real-world knowledge. What a great relief it is to know that no matter what corner you turn, you’ll always have a map in your pocket that helps you find your way back home. How much more convenient it is to just save the bulk of a Walkman in addition to a cell phone…

Great! Now I have an idea! I can start now!


Ideas are worth nothing

We all have probably seen a message like the following on a mailing list:

Q; this is quite draining on the resources as well as jumpy. What can I do to get this resize function called a lot, but without killing the system? Maybe a run loop callback?

A: What are you actually trying to do? So far, this sounds like you’re going about things all wrong, and that’s why you’re getting bad performance.

Q: Sorry, but I am trying to keep my project pretty need-to-know, to deter the real programmers from stealing my idea!

Wait. So we’re all dishonest thieves, yet he’s going to take our advice anyway? Without intending to, this poster insulted everyone on the mailing list. That reminds me of J. Michael Straczynski, writer of nearly every episode of Babylon 5: He once wrote that, whenever he told people at parties that he was a writer, they told him “I’m gonna write a book when I retire”. He found that insulting. Now those people didn’t mean anything by that, but a writer spends years of his life perfecting his skills. Not just spelling and grammar, but learning the subtleties of words, composition, how to structure a story. They have to do research on each subject they write, … why does everybody think they can do the same work once they retire, without training?

That’s why I don’t care about someone stealing ideas. Everyone has hundreds of ideas every day. They are worthless, unless someone actually realizes them. Execution is everything. And just because I have the idea to create something like Word, doesn’t mean I can actually pull off creating one huge application that combines all these ideas into a coherent whole.

Also, while I’m always careful not to underestimate the power of a good idea, I try to keep in mind that I am very likely not the first one to have an idea. When I started out at my current job, I constantly came up with great ideas, and every time was eventually pointed at the corresponding feature request in the issue tracker, which also had a list of stumbling blocks I hadn’t thought of that prevented this from being the simple, easy fix that I originally thought it would be. Be it issues of scalability to 3000 satellite channels, patents, unavailability of worldwide data providers, or whatever else.

Getting started and finishing

So, once I have an idea, the next biggest hurdle is not running out of money before I can start selling copies and make money back. So of course I need to consider the business case, make sure I work out a price that doesn’t just cover costs, but rather also lets me live decently, and sends the right marketing message. But what else can I do to speed up my release?

An answer Matt Mullenweg gave to that question was: “if you’re not embarrassed when you ship your first version you waited too long”. And that’s a great way to start a product. I design my 1.0. Then go through my design and take out everything that isn’t absolutely necessary. What is necessary? To know that, I have to know my unique sales point: What does my application do that none of its competitors do? What makes my app so special, so different that nothing else on the market will suffice? I must find that one aspect, and make sure it’s in the first release. And build everything around it so this central, main use case can be achieved. Cut away everything else. That is my real 1.0.

I can release that, and finance all the other features that bring me parity with the competition with the income from that version. In the beginning, it may just be an add-on to the competition. Then I add the other features back in, bit by bit. And I must remember to not be shy to charge for new features. People saw my 1.0 when they bought it. They knew it only did these few things, and they bought it anyway. It is worth the price to them already. Anything else I add is a gift, a marketing expense. So, I take the features that only work in some countries, but not in all, or bug fixes, things that I can’t put on an ad for a version 2.0, and add those gradually. But I try to stay aware of what people are willing to pay for, what has value to my users, and try not to be afraid to charge for that work.

Think of your users

One major advantage of working out my unique sales point is that it will give me clarity of focus. Whenever I am tempted to add this handy feature and this wish of one customer, possibly saddling myself with additional maintenance work in each release, and adding complexity to my user interface so it can support all those features, I can take a step back and ask myself: Does this solve a problem for the typical user of that 1.0 version I released initially? And if it doesn’t solve an actual problem that my users have, why the hell am I adding it?

Everything needs to be subjected to the user’s needs (which may be, as I implied earlier, different from the wishes they voice – it is my job to find out when there is a mismatch). But that doesn’t just apply to the program design of features and code. It also applies to the entire workflow, up to and including the hardware the user is on, and even the user’s surroundings, and their life situation at this point in time.

To take an example I mentioned before, users are often reluctant to update their software, for fear that an update may break something they rely on. Some developers try to overcome this conservative attitude by forcing their users to upgrade. But now imagine a user writing their diploma thesis: They need to get it finished by a deadline, or they won’t get their degree. They will set up their system with reliable software at the beginning, maybe do a few tests to ensure the things they need work, and then they want it frozen. It may not be a matter of life or death, but it may mean the difference between cheeseburger or caviar for the rest of their lives.

Alternately, they may be on a North Pole expedition, only to find out one week in that my application requests an online activation every week and stops working if that can’t happen.

While I may not share my users’ priorities, may not even know about them, I need to account for them in my design. I need to honor their data, make my file format robust enough that I won’t corrupt the meticulously-collected samples my user collected. I must honor their schedule, and let them postpone updates, let them quit right now before the EMP hits and fries their notebook computer, and honor their priorities. And as much as it hurts me, playing with my program is usually just a necessary evil to users. What they really want to do is write that novel, file those taxes before the deadline, or switch out of my application to take that call from their doctor with those test results.

And I also need to keep in mind that I may go out of business or even die, or just lose interest, and have a contingency plan for that. I can’t just abandon my users after I’ve taken their money. I need to make sure they can keep running my software even if my activation server is down, or that someone who bought my software ten years ago can still get at the data on that unchanged antique Mac they bought it for, even if I long ago stopped developing and maintaining classic MacOS 9 software.

Development overhead

Now that my product has an idea and functions reliably even in the face of adversity, what else do I need to account for so I can create a real finished product and not just an amateurish project? For one, there are a number of tasks that need to be performed. A visible one is graphic design, but I also need to provide support to my users (this tends to take up increasingly more time the more I sell), document the program both for myself (or anyone following in my footsteps) as well as for my users. I already know the program, and I built it, so it works the way I think is most obvious. But everyone’s brain is wired a little differently, and everyone brings different knowledge to the table, so I will have to document things for someone.

At some point I will also sell internationally and need to localize my program. A thing I learned early on was to use native speakers of a language and have them translate into their mother tongue. I’m a German with certifiedly excellent English skills, still I would not recommend someone hire me to translate a German user interface into English. They should pick an English speaker who knows German instead, because it’s easier to understand the gist and subtle nuances of a sentence in a foreign language than it is to actually build an equivalent sentence, even in my own language. Professional translators are worth their money.

Also, localization, documentation and many other tasks need to be performed again for every release I make. So I make a checklist of tasks to be verified, even on dot-releases:

  • test migration of preferences, documents, databases etc. from previous versions to the current one. Users don’t like to have to re-apply their preferences because your program “forgot” them because you fixed a typo in the defaults key. They also sometimes launch a copy of an older version and edit files created by a newer version with them, then re-open them in the newer version later. What will happen? Will the data be inconsistent because the old version didn’t update a new data structure?
  • test the first run experience. Adding a single alert at startup did not seem like much, until I realized that I was now up to three alerts in a row for new users. Also, did I correctly set default positions for all windows? Does the user get bombarded with empty windows and no clue what they do, or are there hints what the app does? Does the user quickly get to a point where they can use the application?
  • What is the cost of this update? What happens to people who bought the old version a day ago, or who just bought an old copy of version 1.0 still sitting in some store on the shelf?
  • Does everything still work?
  • Do certain features require regular maintenance?
  • What happens to people who have another version of my application installed, be it a demo version, the app store version, a web site version … ?

The dastardly feature

And that leads us to the cost of each feature. If you add a crash reporter, you may need to update the list of Mac machine names in its framework. If your application needs a country selector to pre-configure some settings, you may need to update the list of countries whenever politics cause a change in that (and believe me, once you have to watch out for it, you’ll realize it happens more often than you think). If your application talks to several web APIs, you will have to watch each of these for server-side changes that are not under your control.

But these are obvious recurring tasks. What about UI complexity? Every time you add a preference to let the user modify the behaviour of your application because you can’t do it automatically, there is one more item in your Preferences window that the user has to evaluate and discard when searching for that one option. And at a certain point, people will just look at a window full of 20 checkboxes, throw up their hands and ignore your preferences. They might as well not be there.

Also, every new feature can have bugs in need of fixing, can have unexpected conflicts with the behaviour of other features, can break on new hardware released after you release your program. If you don’t notice it right away, users who made their purchasing decision on the fact that your application had this particular feature will not appreciate if you remove it again. You can always add a feature, but you can’t take one away.

Also, adding a feature that only some of your users can use is annoying and perilous. You can run afoul of false advertising laws if a translator isn’t told to remove mention of an unavailable feature. If you add other features that are dependent on these features, you suddenly have a whole slew of UI elements that are useless to a subsection of your users. And really, can it be a major feature for a release if it’s not available to everyone?

And finally: Users don’t think about features like developers do. To sell a feature to a user, you have to figure out a way to make it relevant to them. Provide it as part of a solution to a problem they have, not as a technical data point. Apple did this very well with their FaceTime commercial, showing that it’s not a gratuitous feature for people who’ve been using the telephone before, but rather allows deaf people to use a telephone.

Having a product and selling it

So, now I have the perfect product, it is well-written, based on a decent idea and deep domain knowledge, has a focus sharp like a razor – a unique sales point. It is maintainable and I’ve worked out all the ancillary details I need to support my users, documented the use of the application and prepared an exit strategy. I no longer have a project, I have a real, sellable product. How do I get it out into peoples’ hands?

I need a payment processor. No, actually, I need at least two, in case an exceptionally good sales month causes errant fraud protection to trigger, like it happened to the MacGraPhoto bundle, for example. It doesn’t matter whether it’s two online payment processors, or whether you know that if online sales break, your stuff can still be bought on Amazon, or in brick-and-mortar stores, or whatever.

Also, I need to make it easy for people to buy my software. So I’ll add a simple, non-boolean asymmetric key based locking scheme, but I won’t go overboard with activation or other things that might prevent users from using my software. It is hard to be noticed at all, and I don’t want to risk losing even a single eyeball at this point in time.

But how do I hack the press? I’ll need a press kit, I can do special sales – but not too often. If I as a customer buy a monthly 5-part game, and before the third part is released, I get a newsletter from them telling me I can now get it half-price … Yes, I got it two months early, but it still feels weird. I would wait a month after the last part’s release to discount it, at least. The goal of a special is to get new customers who think they’re getting a deal, not piss off existing customers making them think they paid too much. And it’s not as if I need a good reason for a special. As long as they get a decent offer, users don’t mind if my reason for giving the discount is arbitrary. Also, bundles with other developers’ software that complement mine can be helpful (the support queue can be a good source for information what these programs are). I can join forces with someone else, it’s a special occasion and a deal that press may want to write about.

But I have to mind my surroundings: If I offer a deal on my web site, but not to other dealers, I am essentially competing with my partners. So unless it’s a small thing like a few free coupons for press or users who take part in a survey, I’d better make sure my partners get the deals as well.

And finally, you can join forums (or mailing lists) about topics related to your products. They’re talking about stuff you’re interested in, so it shouldn’t be too hard to take part in the discussion there, maybe help a few beginners with your deep domain knowledge. Don’t just go there and flood them with advertising. Take part as who you are: A person interested in the topic, who happens to also be a developer of a useful piece of software. Be honest. It is all right to mention your product when the conversation heads in that direction, but ensure that everyone in the conversation is aware that this is your program you’re recommending here, every time. Don’t be the baby buggy salesman who crashes a wedding, be the friend who makes cool tools.


Being fair to your competitors

Ollie the Twitterific mascotOne thing that every successful developer will eventually face is competition. When most people think about competition, they think about evil people who want to take your customers away from you, copy your great ideas, and say bad things about you.

That’s nonsense.

In most cases, a competitor is actually a person that is very much like yourself. So much so, in fact, that they chose to develop a similar product, marketed to similar customers. If you talk to one of your competitors, you will find that you share certain interests.

Mind you, I am not claiming that every competitor is exactly like you are. There is often a certain, important, difference. Something, that keeps you from pooling resources and going at the whole problem together. If you weren’t competitors, you might even have become friends. But still, competitors are usually made up of the material that friends are made of, so I firmly believe that one should treat them as such.

I guess the best way to illustrate the ground rules for dealing with competitors is to take an example from real life, and point out what went wrong.

You might have heard about the Twitpocalypse a while ago, an occasion where a number used to uniquely identify a Twitter message became so large, that many Twitter clients had to be revised to avoid problems. The developers of one Twitter client, let’s call it Twitter client A, made a mistake, and users started posting on twitter about the weird issues they were having due to this mistake. The developers quickly started working on a fix.

During the time that it took to fix the issue, the developer of Twitter client B started replying to the messages of users mentioning the bug in Twitter client A, advertising his own product.

In my opinion, this is an abuse of Twitter, and akin to spamming. People were asking about the problem with their existing clients, they were not asking for sales solicitation from a competitor. While it is all right, and even a demonstration of paying attention to your (potential) users, to answer Tweets of users asking generally for a product that does what your product does, or asking about alternatives to one of your competitors, you are essentially intruding on a conversation between other people when you reply to posts about your competitor.

Moreover, it is showing disrespect to your users. You wouldn’t just walk up to a stranger in the street and tell them that their car is crap and that they should buy a new car from you. And you would consider it slimy if a used-car salesman walked up to you when you had a flat tire, to tell you that they have a new car on offer.

Since a developer, even if they’re trying to be fair, is generally biased, they should just have the class to let their competitors (remember, they’re like you) deal with their problems in peace and quiet. Let them have conversations with their customers and don’t intrude. Stay in the public arena, and don’t drag an imaginary “fight” to their doorstep.

It is perfectly fine to highlight the features in your product that your competitor doesn’t have, or even does badly. But there’s no need to bash them. This is your advertising space, why even mention your competitor? Nobody likes the guy who, when his mistakes are pointed out, points out the mistakes of others defensively. That only reeks of desperation. When users come to your web site, they want to know what your program will do to help them.

By virtue of pointing out your features, users will think of those aspects when looking at competing products. Hey, it’s happened to me:

One competitor to one app I was doing pointed out a really trivial feature: Window zooming. I was confused, why would one even talk about this? Then I got a sinking feeling. Didn’t I recently change something in a related area recently? I looked into it, and sure enough, I had broken window zooming without even realizing it.

That was clever. Take advantage of what your app does better, but be fair.

Do not wake the Dragon

Several typical web forums

So much support, so little time…

One of the most depressing aspects of doing your own tech support is the constant barrage of negative feedback. If you are a conscientious developer who takes pride in their work, all the complaints coming in can be very disheartening. Some developers try to balance this out by offering forums for their support. That way, the thinking goes, your users can band together, more advanced users can help each other, and while you are doing actual development work on the program, easy questions will already have been answered, and you can focus on answering the real tough ones.

We’ve seen this work just fine for many programs. Not only did it encourage development of a community of users and a whole third-party ecosystem, but all the talk and content also offered more google results and thus improved discoverability of a product.

However, that was mainly for products that are frequently used and whose use includes constant problem-solving and optimization. Products used by people who constantly use them to create content. Development environments have a large user community, even though the total number of developers among Mac users is comparatively small. iMovie and Keynote users band together to discuss ways to best take advantage of certain features in their presentations.


On the other hand, applications that are mainly used for consumption have been burned by forums: As most users are perfectly happily using the application and don’t need to figure anything out, thousands of happy users have no reason to go anywhere and connect to other users. The only people left to seek out the forums are a few hardcore fans (great people, but sadly always a minority), and people actually having a problem.

Statistics tells us that this severely skews the forum population towards unhappy people. Looks like we’re back in the same place as with support, right?

Sadly, that’s not the case. Your support happens quietly, behind the scenes, one at a time. Nobody ever sees the constant stream of unhappy users made happy by help. The Forum, on the other hand, is indexed by Google, remember?

So not only is the group of people in there skewed towards negativity, but your search results on google are now, as well. Instead of seeing your web site and a few positive reviews, someone googling for your program will be inundated by complaints about every little thing that has ever gone wrong for someone with your program. They’ll think that your program is very buggy, because she doesn’t get any such complaints about other programs.

In the eye of the public

But that’s not all: Customers coming to your forum with a small problem may see a post from two years ago that sounds just like the problem they have, and think badly of you: This problem has been reported 2 years ago, and it still isn’t fixed? What a slow developer!

Never mind that the technical and social reasons for this issue are completely different, and the issue happened for one day two years ago, and the one they have is brand new as of two hours ago…

So Forums are Evil?

Certainly not. I have enjoyed the thoughtful conversations and clever solutions on many forums over the years, and I wouldn’t want to miss those times and everything I learned in the process. But I wanted to sensitize you to the downsides. Look at your application, and consider whether it does anything that would benefit from having a group of users connect their brains. Is it used frequently enough by a large group of people, and is the subject matter complex enough to make a forum worthwhile?

But hey, when in doubt, just try it. But watch for the signals, and be ready to scratch the whole thing if it doesn’t work out well.

Honor, righteous anger and public perception

[The Moose being very peaceful and reconciliatory with Tux]

An honest mistake

Close to ten years ago, I received my first angry e-mail message from an enraged prospective user of my application “Uli’s Moose”. Uli’s Moose is a free, simple application that I did in my spare time, on my own dime, on a student’s pocket money. In essence, the sender of the message told me in colorful prose that he’d tried to download the Moose from several web sites and tried to run it several times, and it had failed every time, and asked why the blazes I didn’t just stop foisting such crap on the world.

What I did, was send a short, terse e-mail back, saying “You get what you pay for, asshole.”

I shouldn’t have.

It’s not that anything bad happened because of that. I never heard back from this person. It relieved my tension to “get them back”. I never got other complaints from people with similar problems. As far as I know I didn’t get bad-mouthed on any forums (there was no Twitter back then, nor were there Mac App Store comments, and few people bothered leaving angry comments on But I don’t know what that person’s problem was. There could have been a bug. There could have been illegitimate mirror sites that I didn’t know about that drove this person to such anger. Had I kept my cool, had I simply and politely replied and asked for more detail on his problem, I might have gained a happy user.

E-mail, forum postings and other digital channels always need to be seen in context, just like usability. And we often don’t have this context. If someone is abrasive, angry or hurtful, chances are it comes from somewhere. Often it is just the combination of anonymous, inhuman comment forms and previous bad experiences with big, anonymous entities. If you expect to be mugged, you’ll see a potential attack in every sudden movement around you. If you expect to be screwed by a software vendor, you see an attempt at trickery in every honest mistake a small solo developer makes.

How much for the vowel, Vanna?

In a recent minor controversy about the move of various companies to a Mac-App-Store-only distribution model, many have focused on the price of the applications and the disproportionate relationship of the complaints leveled at them.

I won’t.

I will instead say that the price itself only has a bearing on the whole matter when you consider that low-priced applications are generally bought at higher volume. As such, there are simply *more* people to cause a ruckus about anything they don’t like. Strength in numbers, if you will.

The actual problem was not moving to the app store, it was the devaluation of words.

Words? Yes. Not just any words, but of the word the developer gave the customer during the purchase of the software. We all learned as children that when you give your word, you can’t just take it back. In law, this is called a verbal contract. In this case, there actually existed a written variant in the license agreement shown to the user before the purchase.

Many of the developers who received angry customer comments actually had made some promise. Be it exclusive access to a pre-release version that never happened, or be it free upgrades until the next major revision of the application. They were written down in a contract, and the nice thing about contract law is that it forbids that one party unilaterally change the contract on the other without giving the other the option to back out of the contract (e.g. by offering to refund them). At least that’s how it works in many countries.

Now, ignoring the legal (non-)ramifications of changing the terms of a contract, what are the social ones? How do you deal with people who tell you one thing, then do something else? Who simply “forget” terms of an agreement you made a while ago, and when reminded of them, decide to simply ignore it anyway? You don’t rely on them anymore? Mistrust? Paranoia?

But how does it look?

Now how does this look from the outside, to the user? Keep in mind, they’ve already purchased from you. They’ve made an investment in a good piece of software. They may have arranged their workflow around it, they may have input their data into it, and they have spent valuable hours of their lives learning to use your program. This may sound exaggerated, but it’s something they can’t get back, and it is something that is worth more than the price of purchase of most apps.

They made this investment of their own, personal resources on the assumption that you would keep developing your software. And they read the license agreement and expect you to hold up your end.

What you effectively do if you suddenly go back on your promise, is trick the user into buying software under a false pretext. It is not about the money, or about there being no future free download. Heck, when you buy a piece of software, you never know how many updates there will be. HyperCard 2.0 was preceded by HyperCard 1.2.5. There was never a version 1.5, nor a 1.9. No big complaints from anyone.

The whole matter is simply one of perception and trust. If you release a version 3.0, you tell your users that there are some great new features and it is worth paying for it again. You are sending a message, and users are willing to pay. If you release a version 2.5, it is just another incremental update. At best, it’s the halfway point between two updates, and it gets a minor additional feature or so.

I doubt anyone would have complained, had this very same binary been shipped saying 3.0 instead of 2.5. But now it’s too late for that. The bigger issue is that the developer forgot what promise had been made. That is unprofessional. What else will that person forget?

From this point on, it is all about how you get out of this situation again. You can’t really re-label it as 3.0: You already showed your hand, you already told people that this is at best a halfway point in your head. You can just ignore it. Swallow the complaints, brace yourself against the storm on the internet and on Twitter — which all your new Mac App Store customers will never get to see anyway, and loyal fans who do the math and realize there is not much of a difference will probably ignore. Swallow the slight loss in reputation and trust.

Or, you could take the classy way out, and fall to your knees:

Tell your users: I screwed up and simply forgot about this clause, it wasn’t intentional. But I made this promise to you, and you were there for me when I started out. I owe you one.

So I will give you this update, maybe even a few more updates with bugfixes via the traditional mechanism, in parallel with the app store. And in one or two releases, I will release a 3.0, and all this will be over. But I will have done right by you, and that’s what counts.

The funny thing is: I’m pretty sure that following that last approach, even if the additional updates were tiny, would cause so much positive PR that it’d probably help sales. Instead of having people complaining about how you didn’t keep your word, you would have people saying: Well, the developer goofed, but in the end came through. I’ll recommend that to my friends if they ask what to buy on the app store.

Other people’s opinions

Amy Worrall: Entitlements of users

Daniel Kennett: Moving to the app store – how not to do it

Hacking the Press – A point for usability in press kits

[Screenshot of the folder window for an example press kit by Realmac Software]

I once saw Adam Engst, of TidBITS fame, hold a talk called Hacking the Press at the Advanced Developers’ Hands-on Conference (the first successor to MacHack). It was a great introduction to how the press works, told with the average programmer in mind, translating the life of a journalist into words we geeks can understand. I don’t remember much of it in concrete details, but whenever the topic of press releases comes up, I realize that I know much more about this stuff than by all means I should, so I guess Adam managed to insinuate himself into my brain quite well.

Recently, Nik Fletcher of Realmac software gave a great interview about press kits, press releases and related matters on the MDN Show Podcast, and I realized that all that great information that was provided there was missing one important answer that I probably first heard from Adam:

Why do I need a nice press kit?

Nik and Scotty were kinda struggling with vague benefits, like “being nice” or “convenience”. But nothing hammers home the point better than a bit of enlightened self-interest:

There are oodles of Mac applications out there. Moreover, there are tons of good ones among them. And all of them send out press releases to the same three score or so journalists who, like Adam, have pull in the Mac world. All of these applications are equally worthy of coverage. So, all those journalists are sitting there, sifting through huge piles of press releases for both bad and good applications, picking out the worthwhile ones. And once they have those, they have to go over these releases again and again, and find the ones they will finally cover in the space they have.

Some choices are obvious: If it’s a “big”, well-known product, it gets covered. If some other similar product has been in the headlines somehow, or hasn’t been in the press (or that particular publication) for a while, a product may get covered to “fill that slot”. Photoshop not done much for you lately? Great! More coverage for Pixelmator and Acorn! After all, users are still looking for good painting and retouching applications. Similarly, if a problem is on the journalist’s mind at the moment, an application that addresses this issue is more likely to be covered.

But what if you don’t fit that pattern? Well, you have to compete with the rest of the worthy apps. It’s a tough call. Now, if your application has a gorgeous press kit with beautiful screenshots/box shots/whatever of your product, and provides a lot of background information and links to relevant articles on Wikipedia etc. that the journalist can make use of for their article, that may just tip the balance in your favor.

We all know how cool it is to find a list of links and information about a particular topic: You start on one Wikipedia page on embroidering and suddenly you’ve read half the site, getting to modern computing via the Jacquard loom, and you’ve learned some interesting things in the process.

You’ve just helped the journalist find an angle that helps cover your product. They can write a witty little intro piece about embroidering, how far it’s come, and if you’re lucky they’ll say that your embroidering application is what all this has naturally led to. Even if the journalist has to truncate the article and that stuff goes away again, the journalist will remember. There’s a personal experience that now connects the journalist to your application, and helps you when it’s up against similarly worthy opponents the next time:

“Let’s see what interesting things the EmbroiderWorks press kit for their new product contains…”

Yes, I’m aware I’m illustrating the ideal, hit-the-jackpot case. But the bottom line remains: When it comes to being covered in the press, you are not just competing against similar applications, you’re also in competition with every other application out there. Many of these are as well-executed as yours.

Having a well-structured, discoverable press kit with the best user experience you can come up with, including URL clippings (.webloc) to lead them to your web site at a double-click, including spec sheets, including a collection of dictionary entries and sources for any required domain knowledge, maybe even including suggestions for articles on topics that include your application, but also others … all of that can help you get ahead of the others and turn a tie into a win.

Sensible Defaults and Anticipating User Needs

I have written before about sensible defaults in various shapes and forms, but I realized I never really wrote about the logical consequence of that in application design.

To recap: For every application, there are usually one or several typical operations and typical workflows that users may have to perform. A programmer needs to determine those workflows, examine them, and split them up into individual work units that the program can perform.

In some cases, that’s all you have to do: Come up with menu items, buttons and controls that perform the individual subtasks and merrily go on your way. But a good interaction design has to go beyond just letting the user do the operations with a computer instead of with a hammer. You will want to optimize the workflow.

One of the fundamental rules of interaction design comes from the early days of the graphical user interface, when all we had were command-lines. Back then, one bright mind realized that we shouldn’t have the user type in anything the computer already knows. That’s how we got menus and radio buttons in the first place. Instead of expecting you to remember terms, the computer will present sensible answers and let you point at one, as if buying cheese at the cheese counter in a remote Swiss village where they still speak that Latin-descended language few others in the world know.

This may seem to no longer be relevant now that everyone is well-versed in the use of what are now standard controls, but it is also relevant to your workflow. Take an FTP program, where you create your web site locally, and then upload it to the server:

The usual workflow would be to have a list of all the files in the user’s folder, have the user select the ones they want to upload and then push a button to trigger the upload. That’s a good design, right?


Look at your workflow. Look at the typical use case. The user has files on disk that are a 1:1 representation of the site the way it should be on the server. Our FTP program knows the folder, it knows the remote directory on the FTP server. The user has changed a few files, and both the local hard disk and the server track change dates. The computer already knows which files the user will want to upload!

So, instead of just being a nice graphical veneer on top of what is essentially the networked version of cp, why not optimize the workflow? If the user does not select any files, why not offer them a list of changed files and ask them: “These 4 files have changed, did you perhaps want to upload them?”

Now, we can’t always assume the user will always want to upload all of these files, so you need to ask. But in that panel that asks, you can let the user remove the files to not upload yet. And always keep in mind that we’re dealing with heuristics here. Some people have one folder containing lots of files for different servers. You don’t want to annoy them by always selecting 50 files for 25 other servers, because she only selected the two for the current server. Not every upload is a full-blown sync.

Unless it looks like something very stupid to do, if the user expressly states an intention, just do that. It’s bad to be a boring app that needs the boring old ten steps when you could do it in five, but it’s worse to be the app that always gets in the user’s way by trying to provide “helpful suggestions”. Clippy the psychotic paperclip anyone … ?

But if the user is vague (like clicking “upload” when nothing is selected), don’t just say “Can’t upload nothing”. If you can, offer to do the most likely thing she was trying to do. And if you have such a feature, maybe it’s a good idea to indicate that in your UI. E.g. mark all files in the list that have changed with a little green up-arrow, and change the name of the “Upload” button to “Upload Changed”, or so. We may not be able to implement the DWIM-button, but we can inch closer and closer to it.

What workflows could you optimize in your (or your favorite) application? Where does your application know things that can be used to anticipate what the user wants?

PS – I had a particular app in mind when I wrote this article, but I didn’t want to point fingers. So I thought long and hard to come up with a different example. Hence, this may seem like a petty, tiny detail, especially in light of the “sync” feature most FTP programs have, but play along. Try to come up with a better example. As long as this article has started you thinking about ways to anticipate user needs, my job is done.

Why Everyone Needs Version Control

I’ve talked about this a couple of times when asked what recommendation I’d give to people starting to release their own software, but a quick search of my site seems to indicate I never actually blogged this. I’m going to postulate something that will seem utterly nuts and over-engineered to some. But it’s true:

Even Solo Developers should use version control.

Marcus Zarra started a great saying that has become commonly accepted among programmers (I’ve mentioned it in my previous posting): You always program as a group of three programmers: Past You, who is a moron, Present You, who is average, and Future You, who is a genius. While this is generally used as a rationale to write readable, self-documenting code and detailed comments instead of just assuming you’ll remember what you were thinking a month ago in two years when you get back to this code, it also helps explain why you need version control.

What is Version Control?

There are many version control systems, or VCSes: Subversion is a well-known one, as are Perforce and SourceSafe, and others popular these days are Git, Bazaar and Mercurial. There also used to be one called CVS, which was kind of the great-granddaddy of most systems used today. They all have a general principle in common:

  1. There is a repository in which you put your code, and that keeps track of every new version of a file, and lets you rewind to any previous version of a single file or the whole project.
  2. You specify small explanation messages whenever you add a new version of your project to the repository (called “committing” the changes), so you can later go through the code and see what a particular change was for.
  3. They handle access by multiple users and make it easy to merge changes to the same file by two users without one user’s changes accidentally overwriting the other.

What does version control get me?

An Additional Backup

As software developers, our most important asset is usually our source code. If we lose that, we can close our shop. Since most version control systems keep the repository on a separate machine, usually a server (either a Mac mini in your cupboard, or one hosted on Versionshelf or a similar service on the ‘net), one thing you get is an additional backup. You can never have too many backups of your most important asset.

Unlimited Undo

Even if you just install the server software on your work Mac or use one of the distributed version control systems like Bazaar and keep the repository on your local hard disk, you still get the version history. Now why would you need to be able to go back to an older version of your application? One word: Bugs.

Face it, software has bugs. And the insidious part about bugs is that they don’t always show right away. You may have released new versions for over a year, and suddenly you find that an old version of your app did something just fine, but the one you have now does it wrong. With version control, you can just get the old version of your application out of the repository. Even better: You can let the version control system show you the differences between the code of these two versions. Just for one file, or for all files.

Yes, you could just duplicate your code folder in Finder when you release a version, but not only does that use a lot of disk space (version control only remembers the bits that actually changed, so is much more efficient), but since you label each change with a commit message, you can keep a copy of much smaller sets of changes. There’s not just one for each version you released, there is one for pretty much each work session, or each small bug in your list of bugs. That makes it much easier to isolate the changes to that particular feature that broke a year ago from the hundreds of other changes to unrelated files.

Freedom to Radically Change your Code

Since you always have a backup of your working code, you can easily experiment with your code. If the experiment doesn’t work out, just don’t commit it to the repository. Or if you already committed it, you can simply copy the working code from an older version of that file and use it to replace the experimental code to get back to a working application.

Also, since version control keeps track of individual changes, you can do experiments “on the side”. Not sure whether you can pull off porting your old Carbon application to Cocoa? You can tell the version control to make a copy of everything (remember, copies in version control are cheap, as version control only keeps track of changes, and a copy is 100% identical to the original, just in a different spot). Then you can start porting this copy to Cocoa. The original is still Carbon, and you can make releases from the original copy. Once the Cocoa-version is finished, you just tell your version control program to “merge” the changes made to the copy into the original.

Version control knows the exact lines that changed, so it can often automatically insert all the changes in the right spots of the original. You’ll manually need to adjust some spots, e.g. where you added a new Carbon window that the new version didn’t have, or where you changed the same line both in the original and in the copy after the copy was made, and that’s it. You have been able to simultaneously pull off a huge change to your application, while still releasing new updates. Your users don’t even notice how involved it was to replace the entire UI.

This technique of making an experimental copy and editing that, then reintegrating it, is called making a “branch”, as the single change history suddenly branches out into two separate lines until it is merged back in again. The same technique can be used for other big changes. Writing a version 2.0? Find a bug in 1.9 that needs to be fixed ASAP? Retroactively create a branch that goes off at the point where 1.9 was released, and fix the bug there, and release it, without having to deactivate, test and debug a lot of new code you added for 2.0.

Documentation for Obscure/Contradictory Bug Fixes

Sometimes, a bug is kind of obscure or incomprehensible, and by fixing it, you inadvertently break something else. Version control can not only show you each line that changed, but it can even show you an annotated version of any source file, mentioning who changed what, where, and what commit message it contained. So, if you find a spot where you need to change a time-out parameter on a function call, and you wonder why it is so insanely high, you can look at the commit message and see that there’s some bug in some router hardware that causes timeouts to return 10 seconds early, about which you’d completely forgotten since you fixed this a year ago.

Now, this can be the last line left over from that fix, you can have accidentally deleted the comment in the source file that said the same thing. Still, version control doesn’t forget. It still knows that this single line is left over from that fix. So you dig out that router, and make sure that your new fix doesn’t break this old one.

Safe Collaboration in a Team

Ages ago, I did web site backend programming together with a CSS guy. We had no version control. Since the source code generated parts of the HTML, the CSS maven would often have to drop into the source code files and change the id or class of this or that element, or add other design-related attributes directly to the HTML to work around omissions in the CSS implementation of certain browsers. Sometimes I added something new and needed to quickly add some simple CSS to be able to see whether my code worked. Every time one of us made such a change to the other’s files, he had to call across the room and ask if he “could have listgenerator.cgi” or whatever.

Sometimes one of us forgot. What happened then was that one would download the file from the development server and start work on his changes. Meanwhile, the other would download the same file, make a change and upload it back to the server again. Then the first would be finished and upload his changed version again, which didn’t have the newest changes, because he’d downloaded it earlier, and suddenly some changes were gone.

This couldn’t have happened with version control. Whenever you commit changes to a file, your version control program checks whether the version on the server is still the same as the one you downloaded when you made the change. If it isn’t, it will complain and offer to merge your changes. Once it has done that, you make sure everything went well, and then commit again.

VCS Philosophy

That last example shows us the main philosophy behind version control: Never lose any data. In fact, in most version control systems, it is impossible to delete a file. You see, you can delete a file on your disk and commit, and that will make it not show up in the newest revision, but since all older revisions on the server still contain that file, you can always rewind to get the file back.

But then, that’s exactly the point of version control: You want to be able to go back to any version of your project, undo any change, no matter whether it is adding text to a file, or actually deleting it.

I hope my incessant rambling has helped those of you who were unaware of the necessity that is version control. As a programmer who ships software to others (particularly paid software), you simply can’t afford to trust your important code and your livelihood to your ability to remember to make copies of a folder and slowly burn them to DVDs. I don’t care what system you use, just use one.