Thoughts on downloads

It occurred to me the other day, that the music industry and software developers are beginning to have a lot in common. The proliferation of digital content, both legal and illegal, has radically changed the way people purchase music. But to those of us who have been distributing our work via the Internet since day one, downloads are not a big deal.

Let’s take a look at how software developers do business and see if it sheds any light on the music industry and their period of transition.

The thing that drives software sales is the notion of “try before you buy.” Gone are the days where you walk into a computer store, scan the shelves for an application, purchase a disk to take home, and pray that it solves your particular problem. Now, every customer has the expectation that the application prove its worth before they hand over their money.

Gone too are the days when you walk into a music store. Unfortunately, the record industry hasn’t realized that this is a good thing. They’re still clinging to the notion that your purchase should be based on nothing more than a 30 second sample. Like software, you have to spend a little time with a song or album before you discover how much you like it.

Of course there’s a need to protect your work so that a potential customer will eventually make the purchase. People are lazy, so you need to find a way to create an incentive to buy.

Some software is distributed by leaving out features until a serial number is entered. A similar technique can be used with music. A great example is Team Love Records which made downloads available for the Rabbit Fur Coat album by Jenny Lewis with The Watson Twins. Every track could be freely downloaded except for one: the track getting airplay (“Handle Me With Care”.) This approach worked very well for me—I knew the hit track from the radio and found out that I loved the other tracks just as much. And, in the end, I was a happy customer.

A similar thing happened with Bob Dylan’s Love and Theft album. A friend of a friend of a friend got ahold of a leaked copy of the album. I found it interesting that a couple of the tracks had really crappy sound: someone made a “mistake” and encoded the tracks at 32 Kbps. You could follow along and get the gist of the song, but I was very happy to “upgrade” on the day of release.

Another approach we’ve taken in releasing our software is to provide additional benefits after a purchase. This can be access to support, a special website or even new features or content. The record industry has done the same thing.

A couple of recent releases come to mind: Cat Power’s Jukebox album and Neil Young’s Live at Massey Hall. The incentive with the Jukebox album was the inclusion of an extra CD with four additional songs. Similarly, the Live at Massey Hall package came with a DVD containing footage from the concert. Both were things I wanted, so the decision to buy was easy.

For artists that you love, getting a complete set of their works is important. If I had been given a free copy of the “basic” CD, I still would have “upgraded” to get all the songs and/or video.

Now, let’s look at one thing that works for software distribution, but isn’t going to work for music: the notion of a time limited demo.

We have a reliable clock, a local file system to record usage, and other mechanisms that make tracking relatively easy. Of course, these things can be overridden or disabled by dishonest users, but the vast majority of honest people make up for it. As developers, we have also learned to encourage users towards the purchase: making demands does not work. Pissing people off will turn them into pirates, not encourage them to buy.

A MP3 file doesn’t have mechanisms for tracking. And we all know how the attempts to add them with Digital Rights Management has gone over with consumers. That’s because it’s a system based on demands: you must be authorized.

Finally, the best thing for business is to make sure you have the best product available. That’s both the beauty and the challenge of any “try before you buy” system. Good products win, bad products are quickly forgotten.

I suspect that the root of the music industry’s problem is this: they have been able to produce sub-standard product for many years. I know there are many albums in my collection that consist of few great tracks along with a bunch of crap that I’d rather not listen to.

And the iPod, which makes single tracks viable because you don’t spend all your time moving physical media around, allows people will buy only the product they find interesting. If the music industry wants to make more money, they need to make something besides one big hit plus filler. Can you imagine buying a software product that had one feature you really needed and 99 others that were worthless? The value is in the whole, not the individual parts. If you make compelling albums, people will buy more music from the artists they love.

In the end, however, I suspect that the large music companies will end up in a similar position as the large software companies. They will have the blockbuster product/artists with a lot of recurring revenue from each new release.

But the most interesting part of this ecosystem will be the independents. The people who have a smaller, but much more loyal following. The people who listen closely to these fans and realize how important they are to their creative works. The people who feel the joy of a customer telling them they rock.

That’s the beauty of this thing we call the Internet: it’s a two way street. And all it takes is a web page to start that conversation.

So you’re going to write an iPhone app…

Welcome! Many people arrive at this page while searching for information about developing iPhone applications. The ideas from this article are expanded upon in my book, iPhone App Development: The Missing Manual.

As we’re all waiting with bated breath for the release of the iPhone SDK later this month, now would be a good time to pass along some of things I learned while working on MobileTwitterrific. Read this now and you’ll save yourself some headaches when diving into the SDK.

Code reuse

Don’t expect to reuse much of your existing code. If you’re using a standard MVC design (which is pretty much inescapable if you’re using Cocoa) then about 2/3rds of the application will require major rework.

From my experience, your models and the infrastructure that support them can be reused without much effort. On the other hand, the multi-touch interface obviates the need for your existing views and controllers.

As an example, the code I use in Twitterrific to download the data from Twitter using NSURLConnection, parse the XML into an NSDictionary and store it in a sorted NSArray was largely copied without change from the desktop application. The controller and view code was all new.

Memory usage

There are some very tight limits on memory usage. You’re given approximately 64 MB of space to work with (about half of what’s available.) If you go beyond that, Springboard shuts you down unceremoniously. That combined with the fact that there isn’t any swap space where unused objects can go to rest, makes for some design decisions that you haven’t had to consider in the desktop environment.

For example, let’s explore how I manage the scrolling list of tweets in MobileTwitterrific. In the desktop version, each tweet in the list is an NSView, while on the phone each tweet is a UIView. The big difference is when these views are instantiated and freed.

On the desktop app, views are created whenever there’s a new tweet and they occupy space in memory until removed from the list. The views don’t have a very large footprint and the supporting infrastructure (NSTableView) works much more smoothly with real objects (rather than some sort of proxy.)

The iPhone, on the other hand, uses a UITableView. This subclass of UIView has delegate methods that ask for a view to display for each row in the table. Of course, you could instantiate a complete list of views and just use the row index to pull the view out of an NSArray. But think about this delegate design pattern a bit: it’s there so you have a chance to instantiate views when they are actually needed. If you have 2,000 names in your contact list, and are only displaying 8 at a time, why do you need to have 1992 views wasting memory?

Basically, you’ll find yourself being as lazy as possible when it comes to object allocation, and being as ruthless as possible when it comes to freeing those same objects.

NIB-less

Try to imagine developing a Cocoa application without Interface Builder. Try really hard. Really, really hard. Seems like a nightmare, huh?

Guess what? This nightmare will become a reality as soon as you start building your iPhone application. There are no NIBs. None.

I don’t think this is one of those “let’s skip it for version 1.0” design decisions. The process of unarchiving the objects in the NIB takes CPU cycles and memory: both things that are in limited supply on the phone. And, as I stated above, you’ll find yourself creating and destroying views much more frequently than you do in your desktop application. (And anyone who has tried to deallocate objects from a NIB knows that’s not so easy.)

Creating views, placing controls as subviews using NSRects, and then setting a bunch of properties isn’t the most glamorous coding in the world, but it’s the price you pay to run on a mobile device. Just be very happy you’re working in Objective-C and not some other crappy language, OK?

Another thing that us Cocoa developers have gotten spoiled with: bindings. You’ll find that all the normal KVC and KVO infrastructure is present, but it saves much less time when you have to establish all the bindings manually with code. If you’re like me, you’ll end up just targeting controls at methods and be done with it.

Complexity

The good news is that the user interface is much less complex. The bad news is that the user interface is much less complex.

If you have a rich desktop application with hundreds of features, you’ll find that it’s hard to pick what you absolutely need. Culling features isn’t easy, but it’s absolutely necessary.

One mental exercise that I’ve found useful is to ask myself “Will I need this feature while walking down the street or sitting in traffic?” Both are situations where there are significant distractions to the task at hand. Does the feature make it easier to interact?

Luckily, not having NIBs and bindings gives you some motivation to get rid of unnecessary complexity. When it’s not easy to add that view with hundreds of controls, you’ll think twice.

Look and feel

Don’t think that your desktop and mobile application will share any look and feel. There may be slight resemblances with regard to branding, but that’s about it. Does Safari look like MobileSafari? Sure it has the same icon, but…

While I was developing the look and feel of the MobileTwitterrific application, there were two areas which were problematic: display contrast and button placement.

Being able to read the display in all kinds of lighting conditions means you’re going to need high contrast. In your office environment, it may seem a bit garish to have a lot of dark elements on light backgrounds (or vice versa), but once you actually try to use these elements in the “real world” it makes complete sense.

This “real world” usage also makes you think about where to place controls. In one case, I placed two buttons too close to one another and found that when I used one hand to drive the UI, my thumb would often hit the wrong control by accident. When I was doing development in my office with the phone on my desk, I used two hands to control the UI and didn’t see this problem.

It’s likely that there will be a simulator in the iPhone SDK. Don’t believe for a second that you’ll be able to use this simulated device for all your development and testing. You have to literally live with the application.

That’s all for now. Let’s go back to waiting impatiently.

What the iPhone specs don’t tell you…

The iPhone technical specifications mention nothing about how much RAM is included nor how fast the CPU is running. Now that I have a toolchain, it was a simple task to take some code from iPulse to investigate.

Note: Apple has obviously not documented the system level APIs that I’m using to extract this information, so take these numbers with a grain of salt. Personally, I doubt that they would bother to make these low-level functions report erroneous information just to protect some consumer spec sheet, so it’s likely that they’re close if not exact.

First, let’s start off with memory. Calling host_statistics() with HOST_VM_INFO returns a count of the number of memory pages in use (the “vm_stat” tool at the command line does the same thing.) Totaling these counts shows that there are 19,500 pages of memory with each page being 4096 bytes. That’s 78,000 KB or 76.2 MB.

Another way to determine memory size is by calling sysctl() with CTL_HW and HW_PHYSMEM. This results in 121,634,816 bytes or 117 MB being reported for physical memory. Similarly, user memory is reported as 93,605,888 bytes or 89.3 MB—close to the 76.2 MB reported by host_statistics(). These calls are equivalent to using “sysctl hw.physmem” and “sysctl hw.usermem” from the Mac OS X command line.

None of these numbers are the nice round powers of 2 that we’re so accustomed to. I suspect that there is some kind of memory partitioning: something like a graphics chip could be using 11 MB of memory and that combined with the 117 MB of physical memory would bring the RAM total to 128 MB.

Now let’s take a look at the CPU speed. Again, sysctl() is our friend, this time using CTL_HW with HW_CPU_FREQ and HW_BUS_FREQ. The results of our test show that the CPU is specified at 400 Mhz with a bus frequency of 100 Mhz.

There have been various hardware reports that place the ARM chip’s frequency above 600 Mhz. Maybe sysctl() is lying to us, or maybe the CPU is clocked down to give improved battery life. Only Apple knows that for sure.

For those of you who care, the source code used for the tests is available.

Benchmarking in your pants

Just how fast is the iPhone?

Let’s run some benchmarks comparing the iPhone to my iMac running Safari 3 on a 1.83 Ghz Intel Core Duo processor:

Test iMac iPhone Slower by
100,000 iterations 0.041 secs. 3.209 secs. 78x
10,000 divisions 0.005 0.413 82x
10,000 sin(x) calls 0.009 0.709 79x
10,000 string allocations 0.010 0.777 78x
10,000 function calls 0.010 0.904 90x

This means that Javascript on the iPhone will take about 80 times longer to run than it does on the desktop. Keep that in mind while you’re writing your Web 2.0 applications.

If you need any more proof of how much slower Javascript is on the phone, take a look at the plotting application I did for C4[1]. Make sure to run it on the phone and the desktop: the performance difference is palpable.

But our benchmarking story doesn’t end there. What kind of performance would we get from a native iPhone application running these same kind of tests?

Thanks to the hard work of many developers congregating at the iPhone Dev Wiki, there is now a toolchain that allows us to create applications that don’t rely on sweet technologies like Javascript.

(Note: use Google if you’re interested in these tools; I’m honoring the request to not link directly.)

That, combined with the talents of Lucas Newman (author of Lights Off and other goodness at Delicious Monster,) resulted in a series of tests written in Objective-C. Here’s the source code: Marbles.zip

Let’s see how Javascript compares to native code running on the iPhone:

Test Native Javascript Slower by
100,000 iterations 0.015 secs. 3.209 secs. 214x
10,000 divisions 0.004 0.413 103x
10,000 sin(x) calls 0.105 0.709 7x
10,000 string allocations 0.085 0.777 9x
10,000 function calls 0.004 0.904 226x

In looking at these numbers, it’s easy to see that there are huge performance wins with native applications: lower function call overhead along with faster iteration and calculation. Even transcendental functions and object allocation sees a 700-900% speed increase.

More reasons for developers to crave a real iPhone SDK.

One thing that’s interesting to note: in the process of writing the Marbles test, Lucas noticed that _objc_msgSend_fpret was an undefined symbol in the ARM runtime libraries (triggered when calling NSDate’s timeIntervalSinceDate: method.) I looked around the libraries on the iPhone and couldn’t find any definitions, nor could a workaround with NSDecimal or NSDecimalNumber be found. Maybe this is one reason why the iPhone SDK isn’t available yet: important stuff is missing.

My guess is that developers just need to be patient. Apple is smart enough to realize that there are major advantages to having third party applications running natively on the iPhone. Not only will these applications be easier to write and faster to run, but they will also add to an ecosystem that makes the iPhone even more attractive to consumers. Apple also realizes that releasing an SDK means having interfaces that don’t change, code that works correctly, and documentation that explains its use.

If you’re a Cocoa developer and haven’t started looking at UIKit, now would be a good time. You have what you need to start experimenting. And you’ll be ready whenever Apple is.

Why stop at the Dock?

If the changes to the Leopard Dock are a good idea, shouldn’t Apple go all the way and do the same thing to the Finder? And then applications, too! Hell, I can totally see these windows flying around with Spaces and Exposé and Core OMFG!

The Finder of the future?

Forget about October, I’m stoked about 10.6! Let’s hope they add more reflections and transparency, too!