Tuesday, December 20, 2011

Launchpad Editor 1.0

Launchpad Editor 1.0

I created a Mac app - my first1.

I’ve been looking for an application launcher for a long time. When you have a lot of apps, like I do, the Dock just doesn’t cut it. Not that I didn’t try: I made various attempts to have a categorised, hierarchical list of applications in the Dock, which tended to get broken or more annoying in different ways with each major release of Mac OS X.

I’ve tried various third-party utilities, but they were all too complicated and customisable. Or, they expected me to type the name to launch it! There’s a reason I use a Mac instead of a UNIX terminal2.

What I was really looking for was something like the Classic Mac OS Launcher:

System 7 launcher screen shot

Simple. To the point.

So when I first heard about Launchpad, to come as part of Lion, it seemed to be just what I was looking for.

And indeed, it was–after I took the time to actually organise my apps. Which took a really long time. Click, drag, wait…wait….wait…drop. Repeat. Sigh.

But it was worth it. All my apps, easily accessible and meticulously organised. Yes, I tend to be a little more obsessive about this than most people, but it made me happy.

And then, one day, Launchpad randomly corrupted its database, resetting all of my apps into alphabetical order and losing all of my folder groups.3 I would have had to do it all over again–and maybe not for the last time, if Launchpad didn’t have its bugs worked out yet.

The idea

I was looking for an excuse to make a Mac app anyway.

I’ve always wanted to make native apps. Even having grown up in the ‘boom’, and being a self-taught web developer myself, I would tell people that what I really wanted to do was make ‘real’ software someday. And they would laugh. ‘Web apps are the future, silly kid!’ But while making web apps has been fun and useful, even the best web UIs have always felt to me like they lack the stability and consistency of a native app. So I’m glad to see the tide turn somewhat back towards native apps in recent years, which affords me an excuse to pursue making them. Anyway.

Once I found out that the Launchpad data is just a simple SQLite3 database, I decided to give a try at making a simple app to manipulate it, such that I could get the job done faster, and with less annoyance, than using Launchpad itself. All it would really need to be is a list view that synchronises to a database, so I thought it would be educational but not too daunting.

Building it

Reading the database was simple: I just used Gus Mueller’s excellent FMDB. I had to figure out the database schema, since it’s not documented anywhere (with a little help - thanks, Andreas!), but it was surprisingly straightfoward. Curiously, it doesn’t look like a database that was generated using Core Data (which was why I didn’t attempt to use Core Data for this either), which makes me wonder Apple is using: straight SQLite C calls? Shudder.

The main challenge was in learning how to do things in AppKit, after I had only just recently learned to use UIKit for making an iPhone app. But they both use similar patterns, the major example being the data source/delegate pattern, so I was pleased to find that I could use many of the concepts I already knew. And when I was having trouble finding documentation on certain subjects, the people in #macdev on Freenode were very helpful, for which I’m very grateful.

One thing I didn’t have to worry about (much) was… memory management! After having to learn retain/release the hard way for my last project, automatic reference counting was a breath of fresh air. It would be hard to overstate how pleased this made me: it allowed me to focus on my application logic, rather than getting constantly distracted by what seems like bookkeeping.

And now it’s done!4 Did I mention you can get it here? Since I couldn’t put it in the App Store (for obvious reasons), I made it open-source on GitHub.

Future

I expect that Apple will improve Launchpad in the future, hopefully by 10.8, making my app unnecessary. It’s typical of Apple to release a minimal-but-polished first version, then add more features later.

Or not. Maybe Launchpad is only for ‘halo effect’ former Windows users brought over to the Mac via their iPhones, who aren’t going to have many apps anyway, and thus maybe Apple doesn’t think anything needs to change. In that case, perhaps I’ll eventually attempt to reinvent the original Launcher myself. (Unless someone else does it first.)

In the meantime, I’m looking forward to making more apps.


  1. That reminds me: I never wrote a blog post about my first iPhone app. Perhaps I’ll come back to it. ↩︎

  2. Not that there’s anything wrong with that. I know a bunch of smart people who use Terminal as much as possible. It’s just a different way of thinking. ↩︎

  3. I think this happened on or around the time of the 10.7.2 update. ↩︎

  4. Well, shipped. Software is never really done, only acceptable enough to release. I still have more ideas than time, so if anyone wants to chip in, here are some places to start… ↩︎

Saturday, December 17, 2011

From around the age of six, I had the habit of sketching from life. I became an artist, and from fifty on began producing works that won some reputation, but nothing I did before the age of seventy was worthy of attention. At seventy-three, I began to grasp the structures of birds and beasts, insects and fish, and of the way plants grow. If I go on trying, I will surely understand them still better by the time I am eighty-six, so that by ninety I will have penetrated to their essential nature. At one hundred, I may well have a positively divine understanding of them, while at one hundred and thirty, forty, or more I will have reached the stage where every dot and every stroke I paint will be alive. May Heaven, that grants long life, give me the chance to prove that this is no lie.

From around the age of six, I had the habit of sketching from life. I became an artist, and from fifty on began producing works that won some reputation, but nothing I did before the age of seventy was worthy of attention. At seventy-three, I began to grasp the structures of birds and beasts, insects and fish, and of the way plants grow. If I go on trying, I will surely understand them still better by the time I am eighty-six, so that by ninety I will have penetrated to their essential nature. At one hundred, I may well have a positively divine understanding of them, while at one hundred and thirty, forty, or more I will have reached the stage where every dot and every stroke I paint will be alive. May Heaven, that grants long life, give me the chance to prove that this is no lie.

Katsushika Hokusai, Japanese painter (1760-1849)

Thursday, December 15, 2011

Last spring, I taught a class at the Columbia Business School called “What Makes a Hit a Hit—and a Flop a Flop.” I focused on consumer-tech success stories and disasters. I distinctly remember the day I focused on products that were rushed to market when they were full of bugs — and the company knew it (can you say “BlackBerry Storm?”). I sagely told my class full of twentysomethings that I was proud to talk to them now, when they were young and impressionable — that I hoped I could instill some sense of Doing What’s Right before they became corrupted by the corporate world. But it was too late. To my astonishment, hands shot up all over the room. These budding chief executives wound up telling me, politely, that I was wrong. That there’s a solid business case for shipping half-finished software. “You get the revenue flowing,” one young lady told me. “You don’t want to let your investors down, right? You can always fix the software later.” You can always fix the software later. Wow.

Last spring, I taught a class at the Columbia Business School called “What Makes a Hit a Hit—and a Flop a Flop.” I focused on consumer-tech success stories and disasters.

I distinctly remember the day I focused on products that were rushed to market when they were full of bugs — and the company knew it (can you say “BlackBerry Storm?”). I sagely told my class full of twentysomethings that I was proud to talk to them now, when they were young and impressionable — that I hoped I could instill some sense of Doing What’s Right before they became corrupted by the corporate world.

But it was too late.

To my astonishment, hands shot up all over the room. These budding chief executives wound up telling me, politely, that I was wrong. That there’s a solid business case for shipping half-finished software. “You get the revenue flowing,” one young lady told me. “You don’t want to let your investors down, right? You can always fix the software later.”

You can always fix the software later. Wow.

David Pogue

Friday, December 9, 2011

Tumblr suspended my blog

Around 5 PM yesterday, I went to post a quote, and discovered that my blog (this) had been suspended by Tumblr. Attempting to post using MarsEdit gave an API error; attempting to get to the blog homepage gave a 404; and attempting to get to any part of the main Tumblr web site got me caught in an infinite redirect loop.

As instructed on the 404 page, I sent an email to support@tumblr.com with everything I knew. And then I waited.

This was a particularly bad time for this to happen to me, because I had intended to pass along my web site URL to some new professional contacts that very evening. There is more to my web site than just the blog, but still: it doesn’t look very professional if following a link on your home page leads to a 404.

To Tumblr’s credit, they replied and fixed my blog within two hours, outside of normal business hours (their main office is in NYC, as far as I know):

Hello David,

Your content has been restored. We are sorry that this problem occurred and will ensure that it does not happen again.

Try deleting your web browser’s cookies for Tumblr.com and see if that helps. Let me know if you still have a problem.

Info on how to delete cookies is at:

http://www.aboutcookies.org/Default.aspx?page=2

Please let me know if there’s anything else I can help you with.

Thanks for using Tumblr!

Quick resolution and an apology, but no explanation. I guess that’s 2 out of 3.

Reading between the lines here, with some relatively unfounded assumptions, here’s my best guess as to what happened:

  1. Tumblr has some kind of automated spam detector, and my blog got flagged. Presumably they don’t have a human reviewing these as it would take too long, so they just automatically suspend the blog immediately. Perhaps it’s because of all of my recent writing about certain braaands? Who knows.

  2. The support person reverted the ‘spam’ flag on my blog, and set some kind of new flag that prevents me from being automatically flagged as spam again.

The above is entirely speculation - I could be wrong about all of it. But, for lack of an explanation from Tumblr, it’s one possible story that fits what I saw.

But this incident made me realise some other troubling things about my use of Tumblr.

The will to back up

I didn’t have any backups of my Tumblr blog. When they suspended it, four years of writing, as far as I knew, was gone. Granted, this is mainly my fault. Tumblr even provides a Mac app that will back up your Tumblr blog to your computer, which I immediately used after my blog was restored. However, this has some further problems:

  • The app has only had a single beta release, which is two years old. This makes sense once you know that the co-founder who wrote it doesn’t work there any more, and in fact doesn’t even use Tumblr any more. But it doesn’t speak well to how long this app will be officially supported by Tumblr. I calculate an 85% probability that it will suddenly and permanently stop working at some point in the future.
  • Even now, the app fails cryptically sometimes. Retrying immediately a few times in a row will eventually get it to work. But that’s worrisome.
  • Backing up is a manual process. Every sysadmin knows that one the cardinal rules of backing is that it must be automatic, otherwise it simply will not get done.
  • It’s Mac-only. This isn’t a problem for me, but it might be for some people. Or it might be a problem for me in the future.

In sum, it would be much better if this app were written in a well-supported, portable scripting language, and open-source, so that there was some reasonable assurance it will continue to work in the future, and so that it could be configured to run automatically. I’m usually a strong proponent of native apps, but in this case, a great UI is not a meaningful advantage and does not outweigh the disadvantages.

Bureaucratic loop

I mentioned before that visiting any Tumblr page while my blog was suspended resulted in a redirect loop. I couldn’t even get to the support site to see if that had any information. I wasn’t even sure to a certainty that I was suspended: my only clue was the URL, which didn’t tell me much.

As a web developer, this is a fairly rookie mistake that I myself have made at least once. It happens when you set up a rule like this to be executed on every page request (in pseudocode):

if (user is suspended) then
  redirect user to "your account is suspended" error page
else
  show the page the user requested
end

See a flaw in this logic? What happens when the user requests the error page?

The same thing that happens when the user tries to visit any page: they get redirected to the error page. Even though that’s the page they requested in the first place. Because there’s nothing in the above logic to handle the case in which the error page was where they were trying to get to. The flow goes like this:

  1. System sets user status to suspended
  2. User requests home page
  3. System checks if user is suspended
  4. System redirects user to error page
  5. User requests error page
  6. Go to line 3

This type of mistake is fairly common, to the point where most web browsers will stop after receiving several redirects in a row from the same site, and display an error message. (Safari’s looks like this.)

The fact that this mistake exists isn’t enough to bother me, because I know how easy a mistake it is to make. But it’s also an easy mistake to fix, and the fact that it’s remained unfixed after at least three years of Tumblr being aware of it suggests something else about Tumblr.

Indeed, the support response above suggests a lack of understanding about why the redirect loop is happening, and the likely conclusion that it must be some kind of ‘cookies thing’ that is probably the user’s fault, probably based on someone’s past experience that cookies can cause mysterious problems that are nobody’s fault and things just start working if you clear them.

Either the bug report about the redirect loop never made it to the bug team, or it was incorrectly bounced back as ‘user error’.

Unfortunately, the advice for clearing cookies is not going to help anyone. To illustrate why, here’s a truth table showing the different states the user can be in (suspended or not, logged in or not) and the result of their actions.

State # Suspended? Logged in? Result of requesting any page Result of clearing cookies
1 No No Success None
2 No Yes Success Go to state #1
3 Yes No Success None
4 Yes Yes Redirect loop Go to state #3

As you can see, telling a logged-in, suspended user (state #4) to clear their cookies will only result in logging them out (state #3). As soon as they log in again, they will be in state #4 again and the problem will occur again, which is not helpful because presumably they want to be logged in. Whereas, if the user is not suspended (state #1 and #2), they will not experience the problem anyway, so there’s no reason to tell them to clear cookies. Clearing cookies does nothing useful in any of these cases.1

So not only have Tumblr not fixed the redirect loop in three years, but instead of fixing it, they seem to have institutionalised some kind of cargo-cult non-fix in their support responses to this problem, which allows the development team to avoid responsibility for the problem.

Ordinarily, as a user, I would shrug something like this off, since it’s a problem that will only ever affect a small number of users, and only those who needed to contact support anyway. But a post today from Rachel By The Bay made me think more about it, after noticing the similarity to what she describes. I would categorise this as somewhere in between a ‘replay’ and a ‘ramrod’ response, as support in this case may be trying to replay a solution to an unrelated problem that happened in the past, despite lack of reasoning or evidence to suggest that it actually works.

Overall, the redirect loop was a minor problem compared to the larger problem of account suspension that I was having. But it still gives me pause because it’s a bureaucratic problem, rather than a technical problem, and the former are the most annoying kind because they’re so hard to work around.

What now?

I don’t mean to pick on Tumblr too much; it’s still commendable that, for a free service that owes me nothing, I received better support from them than almost every service I pay for, especially those from big corporations.

But it’s clear that I’ve placed too much trust in Tumblr, compared to the importance I place on the data I let them keep for me. My resolution of this problem hinged on the fast and (mostly) accurate response from a support person; but as a technical user, I’m used to fixing problems on my own. I can’t predict what’s going to happen to Tumblr as a company, and I’m not comfortable assuming that I will get an equally good support response in the future, for problems caused through no fault of my own, which I am unable to fix myself.

So it seems like it’s time to move back to a self-hosted blog. This will not be fun.

For one thing, I love Tumblr’s clean and simple UI design; I have never seen any compelling alternatives. On the other hand, I mainly use MarsEdit to post these days, so I rarely see Tumblr’s UI any more anyway. Of the ones I know about:

  • Chyrp’s main goal is to replicate Tumblr’s core functionality, including the Tumblr post types. It can even import Tumblr blogs. However, it seems lightly maintained (it was dead and resurrected at one point) and not very compatible with MarsEdit. And there are time costs related to using software that isn’t widely-used, as you’re more likely to run into problems that nobody has encountered before. Like Marco Arment says, you never want to be the biggest user of any software.
  • WordPress is the popular behemoth, but it’s famous for its security holes and performance problems. It seems like every time I read about it, there’s a different caching plugin you’re supposed to use just to get decent performance; this alone seems like something that should be a Solved Problem, built-in to the core functionality. The fact that it’s apparently not is very concerning.
  • Movable Type is also fairly popular behind WordPress, and (if I recall correctly) uses static HTML pages for ideal performance. I still get the impression that it has way too much in the way of features and clutter than I need, but it’s looking like the best option right now.
  • Or I could just write my own, but that’s just so cliché at this point, and there are more interesting things I could be working on.

Migrating data to another system is usually difficult and tedious, especially when you’re as concerned as I am about preserving the original data as closely as possible (including the original URLs, design, etc.) There seem to be very few existing ways to move data from Tumblr to something else, so I will probably have to write my own.

Clearly, it’s not something I’ll be able to do quickly or easily, but having control over my blog should make it worthwhile.


  1. Of course, there may be more cases than the ones I know about, in which case, my analysis would be incomplete. ↩︎
Thursday, December 8, 2011

Wegmans to expand into Newton, MA

Wegmans to expand into Newton, MA

Nice.

At 70,000 square feet, the Newton store will be the smallest Wegmans built in a decade, although it’s still larger than many New England supermarkets.

Previously. Previously.

Thursday, December 1, 2011

…work to empower individuals, not to exploit them.

…work to empower individuals, not to exploit them.

Daniel Jalkut

Monday, November 28, 2011

An easier way to search DuckDuckGo from Safari

I previously wrote about a workaround I made to replace the Yahoo search in Safari with DuckDuckGo, my new favourite search engine. (Other browsers don’t need workarounds.)

An unfortunate complexity of the method I wrote about was that you needed to run your own web server. But I emailed Yegg, the founder of DuckDuckGo, explaining what I did, and he was interested in helping on their end to make this easier.

So, good news: you no longer need to run your own web server for this to work! DuckDuckGo now takes care of that part (which makes sense, since I gather they have a few web servers that they were already running).1

You now just need to add this one line to your /etc/hosts file, restart Safari, and ‘Yahoo’ will be DuckDuckGo from now on:

184.72.115.86 search.yahoo.com

To make this even easier for people who don’t know how to edit their hosts file, I’ve put together a simple Mac app which does this for you. Download it here. Patches welcome via GitHub.

You can also read the support doc on DuckDuckGo, which explains in more detail. Of course, there are still other ways to accomplish this, but I think mine is the best way.

It’s really cool to use a search engine that’s so responsive to user requests, and even willing to collaborate with me. I’m making an effort to do most of my searches with DuckDuckGo now, and only falling back to Google when I can’t find something. (Will you take the DuckDuckGo Challenge?) I hope to see DuckDuckGo give Google some much needed competition.


  1. For the curious, here’s how we did it. (You don’t need to know/understand this to use it.) ↩︎
Wednesday, November 23, 2011

GitHub for Mac 1.1

GitHub for Mac 1.1

Great update that adds per-line committing. This should be a lot simpler for many people to understand than the stage, and covers almost as many use cases. I think I’ll try switching from GitX to this full-time for a while, and see if it works for me as a replacement.

I really admire the way they are rethinking the version control workflow and trying to make it easier and better.

Friday, November 18, 2011

Occupy Flash - The movement to rid the world of the Flash Player plugin

Occupy Flash - The movement to rid the world of the Flash Player plugin

It’s a nice thought, but I don’t think this approach will work. Most people don’t know or care what any of this means; they want the internet to ‘just work’. They’re not going to intentionally do something to make their computer less functional. They don’t care about web developers or standards or building the future. They just want to watch funny videos. Despite how nicely designed this web site is, it’s missing a ‘why’ that most people will care about.

Better would be to somehow convince more computer manufacturers to stop shipping Flash (like Apple already has done). We don’t really even need users to actively complain; the web site owners should notice the drop in the number of Flash-installed visits in their analytics, and maybe add the two lines of code they need to fall back to HTML5 (since their videos are likely encoded in h.264 already). What the manufacturers lack is motivation to do so. I’m not sure what the answer is.

Increased use of iPhones and iPads has largely failed to achieve this effect, mainly because so many web sites detect the device and shuffle those people off to a separate ‘mobile’ site while leaving everyone else with the Flash version. Which is annoying for other reasons, but that’s another rant.

Thursday, November 17, 2011

Marco Arment's Kindle Fire review

Marco Arment’s Kindle Fire review

I find this ‘list of thoughts’ format much easier to read than the narrative style of most product reviews. It covers a wide array of relevant points, while avoiding the tendency to ramble.

[UI problems happen] a lot when waking the Fire from sleep, when it has no connection for a few seconds before the Wi-Fi reconnects.

Reminds me of this interesting article about ‘rapid DHCP’ that Apple uses.

10 of 47