AMBER Alert Usability

If you live in the State of California, you got an AMBER Alert last night just before 11 PM. If you have an iOS device, you saw something like this on your lock screen:

Or like this in Notification Center:

And if you’re like most people, you had no idea what it meant. Considering it’s a broadcast to locate missing children, that’s a bad thing. Let’s examine the usability of this alert and think about how this system can be improved.

Updated August 6th, 2013: Lex Friedman has written a great summary of AMBER Alerts at Macworld. Among the revelations: the text of the messages are limited to just 90 characters!

First Impressions

In our household, there are many iOS devices. At the time of the alert, we were in the living room with two iPads and an iPhone. The alert’s sound is designed to get your attention, and that it did!

Both my wife and I gave each other that “what the hell is wrong” look as I grabbed my iPhone from my pocket. Turns out we weren’t the only ones who were frightened by the sound:

My wife’s first question as I looked at my phone was “Are we having a tsunami?” (we’ve had these kind of emergency broadcasts before.) I replied with, “No, It’s an AMBER Alert”. To which she replied, “What’s that?”

And therein lies the first problem: I had no idea.

Unlike all other notifications on my iPhone, I couldn’t interact with the alert. There was no way to slide the icon for more information or tap on it in the Notification Center to get additional information. Through a combination of Google and my Twitter timeline, I eventually figured it out:

But I was also seeing a lot of people on Twitter whose response to the confusion was to ask how to turn the damn thing off. And since AMBER Alerts aren’t affected by the “Do Not Disturb” settings, a lot of people went to Settings > Notification Center so they wouldn’t get woken again in the future.

That’s exactly what you don’t want to happen when a child is abducted.

Alert Text

In looking at the message itself, it’s hard to tell what it’s about. Starting an alert with an acronym may make sense to the government, but there’s wording that could resonate much effectively with normal folks:

It’s also hard to tell if this is a problem with “Boulevard, CA” or a “Nissan Versa”. And where is Boulevard? And what does a Nissan Versa look like? Who do I call if I see license 6WCU986? In summary, this notification provides more questions than answers.

This one image has answers to all of these questions and more. Why can’t I see that image after tapping on the notification?

The Alert Sound

As I mentioned above, the sound definitely let us know that something was wrong. But we were sitting comfortably in our living room. A friend of mine was driving at the time and probably listening to music from their iPhone on a car stereo. Being startled at high speed is dangerous:

Unlike the devices that existed when the AMBER Alert system was first introduced in 1996, our iPhones and iPads do a lot more than calls and texts. Music and video are immersive activities and hearing a loud horn can be a cure that’s worse than the disease.

Also, we’re all conditioned to immediately look at our phone when the normal alert sounds are used: a simple ding would have gotten just as much attention.

Do Not Disturb

And what the heck is up with this crazy sound happening if Do Not Disturb is turned on? Dammit, it’s my phone and I get to tell it what to do. Stupid Apple!

Well, take a look at your government first:

And if you want the details, it’s only going to cost you $205 to download:

Bottom line: these bugs aren’t going to be easy fixes.

(And if you think getting woken up because of an AMBER Alert is such a terrible thing, why don’t you explain your pitiful situation to this boy’s parents.)

File A Radar

Even though these bugs probably aren’t Apple’s direct problem, I’m still going to file a bug report. If you have a developer account, please feel free to duplicate that Radar.

Apple is in a very unique position to address these issues:

  • It has direct access to millions of customers and their mobile devices.
  • It employs many people with a deep understanding of how mobile devices are affecting our lives.

This is clearly a problem where cooperation between Apple, the Department of Justice, and the public can improve a system where everyone benefits. Better usability with AMBER Alerts is case where “think of the children” isn’t a trite platitude.

App Updates for iOS 7

Like many of my fellow developers, I am in the middle of an update of an app for iOS 7. As you’d expect, it’s a lot more work than previous versions of iOS. But results are stunning: both David Lanham and I have commented that our shipping version was “feeling old and clunky.”

While cranking along on the update, a couple of thoughts occurred to me: how many other developers were doing the same thing and were they going to commit fully to iOS 7? The depth and breadth of the changes in iOS 7 makes it difficult to support older versions of the OS.

So I just asked. I also included a simple question that any developer who was actively working on an update would be able to answer as a sort of CAPTCHA.

After a little over 24 hours, I had my answers:

An overwhelming number of developers are updating apps for iOS 7. Of 575 valid responses, 545 developers indicated that they were working on an update for iOS 7. That’s an adoption rate of 95%!

Of those developers who were working on an update, I then calculated how many were going to require iOS 7 (and drop support for iOS 6):

Just over half of developers (284 of 545) were leaving the past behind. Initially I was surprised that this number was so high, but then I remembered how much time and effort I was putting into my own work :-)

If you’re a consumer of apps, this is great news: it’s likely that your favorite apps will be ready for action come this fall. If you’re someone who has a device that’s a couple of years old, now’s the time to start thinking about upgrading. Many apps will require a device capable of running iOS 7.

After I posted the survey, I heard from several game developers who complained that they didn’t know the answer to the trick question: UIView -tintColor is only used in traditional interfaces. Most of the difficulty in adapting apps is changing navigational and content elements to match the new style. Games don’t have this problem: they’re basically all content. Considering these facts, my guess is that games will have much broader support for older versions of iOS.

If you’d like the raw data and my analysis using Numbers, here you go: iOS_7_Updates.numbers

The Origin of Tweet

Last week, one of my colleagues informed me that the word “tweet” was now included in the Oxford English Dictionary (see “Quiet announcement” at the end of the page.)

The noun and verb tweet (in the social-networking sense) has just been added to the OED. This breaks at least one OED rule, namely that a new word needs to be current for ten years before consideration for inclusion. But it seems to be catching on.

John Simpson
Chief Editor, Oxford English Dictionary

It’s not everyday that a word you helped create gets added to this prestigious publication, so I thought I’d share a bit of the early history of the word “tweet.”

In the early days of Twitter, the service used “twittering” as a verb and “twitter-ers” as a noun. The December 2006 newsletter is a great example of the lingo that was in use back then:

From: "Biz Stone"  
Date: Wed, 06 Dec 2006 07:51:31 +1100
Subject: Twitter Now Supports AIM and More

Hello Twitter-ers!

Things are really heating up at Twitter headquarters these days.  Last month, the number of Twitter users doubled and it looks like it's going to double again before we run out of December. We  thought the best way to react to all this positive activity would be to keep on making improvements. So come on by and check out  http://twitter.com!

…

That's it for now, Happy Twittering!
Biz Stone and The Twitter Team

http://twitter.com/biz

I started started using Twitter at the beginning of December. Like John Gruber and my colleagues at the Iconfactory, I loved our new “water cooler for the Internet.” I was, however, unhappy with using Twitter via the website or Dashboard widgets.

While taking a shower in the middle of December, an idea struck me: it wouldn’t be hard to hook up Twitter’s new API to the Cocoa networking classes and display a table with tweets. So I dried off and started prototyping: the next day I had the world’s first Twitter client running on my Mac.

A few days later, I checked all my code into our repository and Twitterrific was born:

r174 | craig | 2006-12-20 17:54:11 -0800 (Wed, 20 Dec 2006) | 1 line

Initial import

There was a problem, however.

As I started to implement the user interface, it was clear that nouns and verbs were needed. Menu items with labels like “Post a Twitter Update” were both wordy and boring. And as someone who loves language, using a phrase like “Refresh Twitterings” made the hairs on the back of my neck stand up.

So we started calling them “twits”; more as a placeholder than anything. Using the term in January 2007 felt just as awkward as it does today:

@Dan: my wife was using the Mac when your twit popped up, followed by “there’s a guy named Dan who’s looking for love”. Classic.

(Thanks to Jordan Kay at Twitter for digging that tweet up. Also, the “Dan” is Dan Benjamin—in those early days we hadn’t figured out screen names, and as far as I knew, there was only one Dan on Twitter!)

Luckily, things were about to change. On the 3rd of January, I checked in a temporary application icon. I always check in something crappy as an inspiration for the talented folks I work with:

r215 | craig | 2007-01-03 13:46:11 -0800 (Wed, 03 Jan 2007) | 1 line

Added a temporary application icon. Updated preferences panel (with quit and about info.) Tweaked on window size. Added expanded size to preferences. 

Less than 24 hours later, David Lanham sent me something much better.

I couldn’t check it in quickly enough:

r225 | craig | 2007-01-04 13:21:01 -0800 (Thu, 04 Jan 2007) | 2 lines

Added new app icon

We didn’t know it at the time, but this is also the moment when a bird became synonymous with Twitter. Prior to that point in time, Twitter’s only identity was a logotype.

Work was proceeding at a very fast pace during the first week of January 2007. Beta releases were frequent and widely distributed. Fortunately, the folks at Twitter were using our app with it’s snazzy new bird icon. One of our beta testers was an API engineer named Blaine Cook who sent me the following email:

From: "Blaine Cook" <[REDACTED]>
To: "Craig Hockenberry" <[REDACTED]>
Date: Thu, 11 Jan 2007 18:29:01 -0800
Subject: Twitterific

Hey Craig,

I work on Twitter with Jack, and just wanted to ping you re: Twitterific. First off, great work - I love it, and I think so does everyone else in the office! :-)

Two thoughts; first, how about changing "twit" to "tweet" - the "official noun" is "Twitter Update", but that's boring...? 

Second, I'm in the process of building a real (re: flickr-style) authentication API, so that you'll be able to obtain tokens for users without having to store their usernames and passwords. I don't want its pending release to stall your development or release date, since we will continue to support basic auth for existing clients, but would you be interested in beta-testing the api machinations? 

Thanks again for Twitterific!

blaine.

(In retrospect, this email is also the first hint that we spelled the app’s name wrong!)

It’s rare to have unanimous agreement when naming things in software, but in this case everyone loved the word “tweet”. I quickly updated both the app and the website:

r263 | craig | 2007-01-12 11:46:22 -0800 (Fri, 12 Jan 2007) | 1 line

Changed "twits" to "tweets". Removed auto launch of Twitterrific web page. Added link to Twitterrific web page in config window.
r2183 | craig | 2007-01-12 11:44:07 -0800 (Fri, 12 Jan 2007) | 1 line

Changed "twits" to "tweets"

And not a moment too soon! We released the first version of Twitterrific just three days later with the following copy on the product website:

About Twitterrific

Twitterrific is a fun little application that lets you both read and publish posts or “tweets” to the Twitter community website. The application’s user interface is clean, concise and designed to take up a minimum of real estate on your Mac’s desktop.

This is the first time “tweet” appeared on the Internet in reference to something you do on Twitter.

Our new app was a hit with users everywhere. We even got a mention in Twitter’s next newsletter:

From: "Biz Stone"  
Date: Wed, 17 Jan 2007 07:37:07 +1100
Subject: =Things Are Heating Up At Twitter

Hello Twitter-ers!

…

Continued Hotness: Twitterrific

The folks over at The Icon Factory have created a brilliant little application that lets you both read and post updates to Twitter. The application's user interface is clean, concise and designed to take up a minimum of real estate on your Mac's desktop. Twitter headquarters is sporting this little jobbie on every monitor in the house! Download it for free from The Icon Factory web site.

Twitterrific: http://iconfactory.com/software/twitterrific

…

Things are heating up!
-Biz Stone and The Twitter Team

http://twitter.com/biz

Unfortunately, the work I had done to expunge “twit” from our app was not complete: I had forgotten to remove it from some button tooltips. After the release of version 1.1 on January 25th, “twit” was gone for good.

Even though the use of the word “tweet” spread quickly, Twitter took awhile to embrace the new terminology. Even after several months, “twitter-ers” were still “twittering”.

As far as I know, the first time “tweet” appeared on Twitter’s site was when they referred to our product. (And yes, there was a point in time when the founder of Twitter would send us feature suggestions!)

Almost a year later, “tweet” was used on the company blog (but again, in a quote by a third party).

The word “tweet” didn’t appeared unquoted on Twitter’s blog until June of 2008. Coincidentally, it was in reference to the WWDC where we won an Apple Design Award for Twitterrific!

It still feels strange to hear a word I helped create be mentioned over and over again in the media. It’s a great word to go along with a great service, and in the end, I’m just happy we’re not calling each other twits!

Addendum – July 13th, 2013

I dug around through my Twitter archive and came up with some interesting tweets that show how and when the first Twitter client came to be.

The first notion that Twitter didn’t belong solely on the web happened on December 5th, 2006 (a couple of weeks before the first check-in in the Twitterrific repository.) This line of thinking was inspired by a tweet John Gruber had posted about the Dashboard widget he was using:

Less than an hour later, I posted this:

A couple of days later, I started poking around with the new Twitter API:

(Note that in the early days of Twitter, the website was designed around @jack’s original idea of posting status messages. The user name was implied in the post, hence “Craig Hockenberry” “is experimenting”.)

By the 20th of December, I felt confident enough in the state of the project to go public (that’s also the day that the prototype code got checked into the repository):

At the Iconfactory, everyone gets a two week Christmas break. I’d rather code than shop :-)

Unlike many products, we knew the name of what we were building very early on:

And from this point on, I never posted from the website again:

Here’s the first tweet with a source parameter (that tells Twitter which client posted the tweet.) We worked with Twitter engineering to implement this, and for a long time Twitterrific was the only source besides “web”. Note that this happened just two days before the release!

Of course on January 14th, 2007, the release was announced on Twitter:

Been There, Done That

We’re all thinking a lot different today.

Designers and developers alike are coming to terms with Apple’s latest iteration of iOS. As I tweeted just before the announcement, there is only one way to describe it:

shock |SHäk| noun
• a sudden upsetting or surprising event or experience.

Those of us who’ve been around awhile had a similar experience 13 years ago. Apple switched from the Classic interface in Mac OS to a new Aqua interface. As fate would have it, I was in the room with some of my colleagues when Steve Jobs introduced a UI “that you wanted to lick.” We all left that keynote in the same state of shock as we experienced yesterday.

I think it’s useful to look at the history of Aqua while thinking about the future of iOS 7.

Some designers are saying that the new look is “over the top.” The same thing was said about Aqua over a decade ago. And in succeeding years, that original UI has continuously been refined to what we see today.

We’ve become accustomed to Apple’s incremental approach which continuously refines their products. This is typically an additive process where new features are included or existing ones are improved.

But with major user interface changes such as Aqua or iOS 7, Apple has another tendency: they overshoot the mark. Their incremental approach then becomes one where unnecessary items are removed (such as Aqua’s stripes) or improved (excessive shadows and transparency are toned down.)

There’s a good reason for this: it’s much easier to take away elements from a design than it is to add them. Simplicity is achieved by removing that which is not really needed.

One parallel with iOS 7 and Aqua that I don’t expect to see: an evolution that takes over a decade. There are a couple of reasons for this.

The first is that the pace of development for iOS is much faster than we’ve ever seen for OS X. Ask any developer and you’ll hear the same thing: it’s a constant struggle to keep up with Apple’s improvements on iOS. Shit happens, and it happens quickly.

Another is the amount of time Apple’s designers have had to work on this project. The decision to put Jony Ive in charge of the interface design happened in October: a mere eight months ago. A major overhaul of a system-wide interface takes much longer than that.

It would not surprise me to learn that the developers had a very short time with the graphical assets we saw yesterday (think in terms of weeks.) This would also explain why the first beta is only available for smaller screens. The development work to support larger screens is relatively easy, but specifying the layouts and generating the assets is much harder.

Another important aspect to consider is the conditions where this new user interface was being evaluated. Every iOS developer who was using iOS 7 prior to yesterday’s announcement was using a security screen. These screens distort the colors and other elements on screen. Try looking at your laptop screen with polarized sunglasses and you’ll see what I mean.

Apple’s “doubling down on secrecy” also played a part. No friends or family were able to see an engineer’s work-in-progress. It’s likely that no one outside the engineering organization was able to give feedback on what they saw. I can think of a few types of users where this kind of criticism is essential: kids that can’t read, friends with vision impairment and parents with failing eyesight.

The good news, and reason I think that we’ll see many improvements before the fall, is because these kinds of surface changes are relatively easy to implement.

Which leads me to my final points: what are the most exciting parts about what happened yesterday?

It’s hard to tell from the keynote, but all of the interactions that surround the app you’re using are vastly superior. Unlike the visual redesign, the work on Springboard feels more mature. It’s likely that work has been underway for a much longer period of time (probably before last year’s WWDC.) Moving around in iOS is so much more fluid and natural.

Like with Aqua, these fundamental changes in how things work will stick around for a long time. We may complain about how things look in the short term, but improvements in usability will be something that we value much more in the long term.

But more importantly, and more subtly, is the change of focus within the apps themselves. In the design of Twitterrific 5, we went through the process of figuring out what content was most important and then designing controls around that information. Previous designs focused on the control structure first and then filled it with content.

(It’s also interesting to note that apps like Twitterrific and Vesper, which take this content-centric approach, also immediately feel at home on iOS 7.)

It’s clear that Apple’s designers have done the same thing: their focus has shifted towards content. I can’t wait to see what happens to the iOS ecosystem when other designers and developers follow their lead. That path forward won’t be easy, but it will take the platform to a whole new level. Yet another example of “can’t innovate any more, my ass”.

Launch Services Woes

For the past week or so, I’ve been suffering from slowness in the Finder, corrupted icons and terrible performance in our version control client (Versions).

Today, I decided to do something about it. The first step was to sample Versions while it was beachballing. The app was spending most of its time in [NSWorkspace iconForFile:]. That, along with the corrupted icons I was seeing in various apps made me suspect that there was a corrupted database somewhere. But where?

After a lot of Googling, I finally found this link. The path to lsregister has changed a bit in Mountain Lion, so this is the command I ended up using:

/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -seed -r

My development machine immediately felt like it was running at normal speed (I refuse to say snappy until they update the Mac Pros.) And, of course, as soon as I figured that out, I found that someone smarter had beaten me to it.

So how did this happen? In looking at the documentation for the Launch Services database, there is a lot of information that’s collected when applications are first launched. As developers, we launch applications all fricken’ day. And we also know that pounding on a database is the best way to break it.

So, the next time you’re seeing general slowness on your Mac, don’t forget to give Launch Services a kick in the pants. Guaranteed to be more effective than zapping your PRAM.

Logging with Xcode Breakpoints

If you don’t already know about it, setting actions for breakpoints in Xcode is a great way to monitor repetitive code without adding a bunch of NSLog() to your code.

After setting a breakpoint, right-click and select “Edit Breakpoint…”. Then select “Debugger Command” for the Action. You can enter any valid debugger command at this point. When you check “Automatically continue after evaluating”, the debugger will run your command and your code doesn’t stop. Sweet.

This approach works great when you want to log the contents of a variable by entering a command like po myVar. But there’s a problem: I often want to know where this variable is getting logged, so I ended up creating another breakpoint with a script print "myMethod in myClass" (in lldb) or echo myMethod in MyClass\n (in gdb) command.

Great. Now you have to manage two breakpoints instead of one. Worse, when you have code like this:

for (MyClass *class in aCraploadOfClasses) {
    if (class.propertyThatIsRarelySet) {
        [self doSomethingWith:class];
    }
}

You can’t use the two breakpoint trick when you want to track class before it’s sent to -doSomethingWith:.

It’s taken me a way too long to come up with what is now a totally obvious solution: make the debugger command call NSLog!

For example:

Let’s break down the debugger command a bit:

p (void)NSLog(@"%s: %@", _cmd, syncItemId)

The _cmd is a C string with the current method name (it’s passed to every Objective-C method by objc_msgSend). At runtime, _cmd makes a very good replacement for __PRETTY_FUNCTION___. The syncItemId is the thing I was tracking in several different methods of my class. The void return value is needed to keep the p command happy.

This little discovery is going to save me tons of time: no more dropping into Xcode to add a line of code that you’ll end up deleting after tracking down the problem. Hope it helps you, too!

A Retina Web

A tweet this morning by James Duncan Davidson got me thinking about the future of Retina images on the web. Before I start talking about the future, let’s take a quick look at the past.

There was a time, not too long ago, where many of us were trapped behind 56kbps modems with 256 color displays. Much time and effort was spent on hacks that made images work well within those constraints. High compression settings and dithering with limited color palettes all combined to get the best quality from the hardware of the day.

Thankfully, as hardware became more capable, these hacks have become a distant memory. Our “solutions” completely ignored the effect of increased bandwidth and didn’t age gracefully.

Now, let’s look at the present. We’re at another tipping point with network speeds and display resolutions. Mobile networks are getting a lot faster and displays have reached a point where we can’t see individual pixels. And attempts to work around current limitations feel dangerously close to those of the past.

There is a movement to improve HTML so it’s more responsive to a wide range of devices. There’s also Javascript that replaces images dynamically. To me, there are a lot of similarities between these techniques and the hacks we had in the late 90′s.

The main problem is that it’s very difficult to determine what type of image is best for the viewer. Screen size is no longer a good metric: my iPad 3 has more pixels than my desktop computer. Similarly, my iPhone’s LTE is nearly an order of magnitude faster than the wired DSL connection in my office. As the device and network ecosystems become more diverse, this problem will continue to get harder to solve. (Remember how much fun sniffing User Agent strings was?)

The only sensible way to move forward is to use a “one size fits all” approach.

Of course, your visitors with the most capable hardware and network won’t be served the most optimal image. Nor will those who have older screens on slower connections.

Your job is to figure out what aggregate size works best for your audience, not to try and outguess what kind of device or network I’m using. Use image compression to create a payload that keeps everyone happy and as needs change adjust that size accordingly.

Behind The App: Twitterrific 5

I’ve always loved shows that take you behind the scenes of creative efforts: Project Runway and Classic Albums being two of my favorites. Here’s one about the development of Twitterrific 5.

Since a lot of the people reading this aren’t developers, I’m going to keep the jargon to a minimum. You’ll be able to enjoy this piece even if you don’t know what an Xcode is.

Statistics

To get an idea of the scope of the project, and see who worked on it, let’s look at a few numbers.

The first source code file was created on February 15th, 2012. Since that first check-in, there have been 2032 changes resulting in 824 files. Of those files, 73% are source code, 25% are images, and 2% are other assets such as fonts and sounds.

Sean Heber was responsible for 976 changes, while I came in second with roughly half as many (557). Tyler Anderson made 397 commits and David Lanham followed that with 95. Anthony Piraino and Gedeon Maheux picked up the rest.

We did weekly beta releases between October 26th and November 19th. The following day, we submitted the build to Apple for approval, which happened one week later. The app was released today, which is actually yesterday in Japan. :-)

Twitter Changes

If you’re at all interested in Twitter’s development ecosystem, you know that approximately six months into our product development there were some major changes announced.

In August, a posting on Twitter’s developer blog announced that changes were coming. In spite of the new requirements and limitations, we were happy to know that our API access wasn’t going to be revoked. Since the early days of the project, we had been worried that third-party development might be eliminated completely.

As more details about API 1.1 became available in September, we became even more upbeat about the changes. There were a lot of improvements in the API and the new infrastructure was extremely robust. Adapting our existing code to the new API took very little time and allowed us to simplify a lot of our internal code. It’s good to know that management’s decision to control the core Twitter experience hasn’t affected their great API engineering.

At this point in time, we also learned that we had plenty of user tokens for the upcoming version. We agreed with our friends at Tapbots, there is no reason to panic.

One downside to the limit of user tokens is that we can’t afford the “cost” of a free app. If someone downloads a free version of Twitterrific and then uses it once, we can never reclaim that token. Tokens are a scarce resource that developers have to manage carefully in order to recoup their development costs. If you’re holding out for a price drop with our app, you’ll be disappointed. The price of Twitter apps is going to rise from now on.

Development Approach

So when you have five people working on a piece of software, how do you go about it?

This time around, we took a much more design-centric approach. When you have a large project, be it a movie or a piece of software, you have to have someone calling the creative shots. For Twitterrific 5, that person was David Lanham.

We’d done Twitter clients before and honestly weren’t that enthused about doing another one. That was until we saw a complete and clickable prototype that David had created. That “wow!” moment you have when you launch and start to use Twitterrific 5 is something we experienced last February. We all knew we had to make this real, even if it was a bit crazy. Our foreman, Gedeon Maheux, made the call and the project began.

Some natural pairings occurred between the three developers and single designer.

As senior developers, Sean Heber and I decided to split the workload between the front-end and the back-end. Sean had a part in everything you see on screen. I had a part in everything you see going over port 443 (for you non-developers who won’t get that joke, that’s the secure network connection that the Twitter API uses.)

This turned out to be a great decision. The user interface doesn’t depend on knowledge of how data is transported over the network, processed and then cached in a database. In fact, in the early stages of the project, much of our back-end existed as a separate project with no user interface. It used automated tests that exercised multi-threaded access to the Twitter API. This independence between the UI and the network services allows new APIs to be added quickly and easily.

(AND IT MAKES ME KING OF THE BACK END IF YOU KNOW WHAT I MEAN)

One of the benefits of writing your own version of UIKit is that you have a pretty complete understanding on how to use it effectively. All the sexy animations and views you see in the the app are Sean’s doing. As he continued to amaze us all, we came up for a word for what he does: juice. For example, just the other day, he closed an issue titled “Add JUICE™ to Photo view”. (You’ll see that change in the 5.0.1 release that’s in review now, and yeah, it’s great.)

Splitting the front and back-end work between Sean and myself had another benefit: we were constantly optimizing our code so that it would make the other guy’s code work better. A lot of people have commented on how fast Twitterrific feels: hundreds of iterations made that happen.

Another pairing was between David Lanham and Tyler Anderson. From the start, we knew that we wanted customers to have control over the appearance of their timelines. Since Sean had done of version of UIAppearance proxy in Chameleon, that was a natural choice to accomplish our goals.

What happened next though, surprised us in a very good way. David started using Xcode.

Since Tyler was writing code that allowed all the appearance modifications to be collected in a single file, it was easy for David to go into that file and tweak the settings to get things exactly as he wanted. Any coder who’s worked closely with a designer had heard these phrases: “Can you replace this image?” “Tweak this color please!” “Nudge that button to the right a few pixels.”

Instead, David was adding files to Xcode and modifying UIColor and UIEdgeInset definitions by himself. Letting the designer take control of his designs, do test builds, and refine the interface produced some amazing results. And it let our developers focus on what they do best: typing code.

As work progressed on the product, we realized we were making something special. When that happens, all sorts of crazy and wonderful things start to form without you really knowing how or why. The best example is when Sean and David added gestures. Twitterrific was already in beta at that point and we were completely happy with the action menus, but the two of them went quiet for a couple of days saying only they were working on “something cool”. And they were right: we can’t imagine using the app without gestures now.

A Clean Slate

So now that you’ve heard about what led up to today’s release, let’s finish with some thoughts about future directions.

As soon as you launch Twitterrific 5, you’ll realize that it’s a clean slate. The visual design is obviously a fresh start, but everything under the covers is as well. When presented with a clean slate, you’re very careful what goes on it. It’s best feature is simplicity. I wrote about Gruber’s First Law of iPhone Development four years ago:

Figure out the absolute least you need to do to implement the idea, do just that, and then polish the hell out of the experience.

That still holds true, and we feel like we’ve done the least and polished the most.

We are well aware that people are going to complain about missing features: push notifications and streaming are obvious examples. But so are trends, and video support, and in-line photos, and… well none of that matters. We believe in building opinionated software.

The product you have in your hands is what we wanted and needed it to be. As the tagline on the website says, “A simply beautiful way to tweet.” We achieved that goal.

Personally, I find myself actively disabling notifications in most of the apps I install these days. Notifications are great when used in moderation, but it’s very easy to use them to the point of distraction. Since I read Twitter as free time permits, I don’t need a reminder. Similarly, a constant flow of streaming tweets interrupting my day sounds more like a bug than a feature.

But guess what? That doesn’t matter either. I’m just one of the opinions that made this software.

And now we’re going to start listening to our customer’s opinions. We’re all excited to get feedback from a larger audience and see how that fits in with our new minimalist vision. If you think Twitterrific is good now, just wait until you see what happens with your collaboration.

iPhone 5 Scuff Remover

Removes unsightly scratches, dings and scuffs IN MERE SECONDS! *

Get yours NOW!

And we think you’re going to love it.

Especially since you know who isn’t here.

* black iPhones only

Retina for Masochists

Today we released an update for xScope that supports the Retina display. As I alluded to on Episode 14 of The Talk Show, this update was harder than most. The 68k to PowerPC, Carbon to Cocoa, and PowerPC to Intel transitions were no walk in the park, but this update really kicked my butt. Here’s hoping that sharing some of the things I learned along the way will help you with your own Retina work.

For most developers who are working strictly in window points, an update for the Retina display is a fairly straightforward process. xScope, however, does a lot of work with both pixels and points. And that’s where the fun begins…

Mouse Input

The first gotcha I encountered while doing the Retina update was with mouse input using NSEvent’s +mouseLocation. The team at Apple has done some amazing work making sure output looks stunning on the Retina display, but being able to get high-resolution input is definitely lacking.

There are two problems at play here. The first is that mouse coordinates can be reported for coordinates that do not exist on any attached screen. The second is that the NSPoint does not contain enough resolution to address every pixel on screen.

To deal with the first problem, I used an NSEvent category that clamps +mouseLocation results to valid coordinates.

For the second problem, the only workable solution was to capture the +mouseLocation and then track -keyDown: events so the arrow keys can home in on the destination pixel. Yes, kids, that’s what we call a painful fricken’ hack.

Window Positioning

The next big headache was caused because you can’t set a window’s frame using non-integral points.

xScope does this a lot. The best example is with the Ruler tool: the origin of the ruler can be positioned to both even and odd pixels on screen. The red position indicators are also small windows that point to individual pixels in the ruler window.

The workaround is to make an NSWindow that’s larger than you need and then adjust the bounds origin of the NSViews it contains. The pain here is that it immediately introduces a dependency between windows and views. For example, the position indicator windows need to know if the view they’re hovering over has had its bounds origin shifted.

Pixel Alignment

There are many cases where xScope has to align to a pixel boundary. I found myself using this pattern many times throughout NSView -drawRect: code:

CGFloat backingScaleFactor = [self.window backingScaleFactor];
CGFloat pixelWidth = 1.0 / backingScaleFactor;
CGFloat pointOffset = lineWidth / 2.0;

The pixelWidth tells you how wide a single pixel is in points, while the pointOffset can be used to align a coordinate so that it straddles the Quartz drawing point:

NSBezierPath *line = [NSBezierPath bezierPath];
[line setLineWidth:pixelWidth];
[line moveToPoint:NSMakePoint(point.x + pointOffset, 0.0);
[line lineToPoint:NSMakePoint(point.x + pointOffset, 100.0);
[line stroke];

Another common pattern was to use the backingScaleFactor to align a coordinate to the nearest pixel in the view:

NSPoint point;
point.x = floor(x * backingScaleFactor) / backingScaleFactor;
point.y = floor(y * backingScaleFactor) / backingScaleFactor;

Of course you can do much the same thing with NSView’s -centerScanRect:, but in my experience it’s much more common to need aligned NSPoint values when you’re doing custom drawing. Creating an NSRect just to align the origin is a pain.

Flipped Coordinates

As Cocoa developers, we’re used to the pain and suffering caused by flipped view coordinates. Retina support can add a new dimension to this headache when you’re dealing with pixel coordinates.

Say you have a flipped NSView with an origin of 0,0 and dimensions of 1440 x 900 (e.g it covers the entire Retina screen in points.) Y coordinates on the screen can range in value from 0.0 to 899.5. When those coordinates are flipped, the range of values then become 0.5 to 900.0: which is off by a pixel (half point) if you’re trying to address the full range of view coordinates. The solution is to adjust the flipped coordinates like this:

NSRect windowRect = [self.window convertRectFromScreen:NSMakeRect(screenPoint.x, screenPoint.y, 0.0, 0.0)];
NSPoint viewPoint = [self convertPoint:windowRect.origin fromView:nil];
	
CGFloat backingScaleFactor = [self.window backingScaleFactor];
CGFloat pixelWidth = 1.0 / backingScaleFactor;
viewPoint.y -= pixelWidth;

I’ve always wondered why there’s this odd note in the +mouseLocation documentation:

Note: The y coordinate of the returned point will never be less than 1.

Even though it’s a lie, the extra pixel does make the coordinate flip work correctly—and now you have to take care because that pixel can be a fractional point.

Summary

Hopefully my trials and tribulations will help you in your own development. The good news is that the beautiful results on the Retina display make all this hard work worthwhile.