Archives for : postedfromipad

Pre-announcement: All-day Core Audio tutorial at CocoaConf Columbus

Back in April, I wondered aloud on Twitter:

Wondering aloud: lots of computer conferences have a one-day tutorial beforehand, usually for beginners. Would anyone want an advanced one?

This is something I’ve been thinking about from the arrangement of the Mac/iOS conferences that typically have a beginner tutorial on day one, then eyes-forward sessions and other contents starting the next day. It seems to have the unintended effect of bifurcating the audience: the intermediate and advanced developers roll in on the second day and it changes the composition of the crowd and the feeling of the group. The sense of “we’re all in this together” gets a little lost. What could we do to get those intermediate and advanced developers in on the first day, mingling with the newbies at breakfast and lunch? Well, we could try to have a tutorial on topics sufficiently advanced that it would be worth the time and expense for intermediate and advanced developers to arrive early for tutorial day.

It seemed like an interesting experiment, and Dave Klein of CocoaConf was game to give it a try. But what goes into an “advanced” tutorial? We could do a day’s worth of stuff that you only get into after a year or two of professional development — managing large code-bases, fancy UIKit tricks, expert XCode wizardry, etc. — though it’s likely five different instructors would come up with five different sets of topics to cover.

Another idea: pick a single advanced topic and really dig into it. Maybe something that people are aware of but haven’t had time to tackle. Something that’s so renowned for its challenge that the best way to learn it would be to just sit down with an expert for a day and work through some code.

Something like, Core Audio, you suppose?

Yep, that’s exactly what we’re doing. On Thursday, August 9 — the first day of CocoaConf Columbus — I’m going to do an all-day Core Audio intro tutorial. I haven’t hashed out the schedule, but it will basically be geared to projects that we can bang out in a tutorial setting and that do something interesting. I might draw from the book, but I might throw in some all-new material… just this week, I was working on code for an ADC support incident and realized that a basic web radio client could be explained and written in about two hours, so that’s at least possible (and ironic, considering we chose to leave Audio File Stream Services out of the book). Surely, the afternoon will have to be all about Audio Units.

Pre-requisites: as with the book, you’ll need a reasonable comfort level with C — not expert level, but not afraid of malloc, sizeof, or * either. Not sure if I want to require a device or make everything simulator-friendly. Guess you can watch the CocoaConf page for that.

Anyways, Dave and family are going to be focused on CocoaConf DC for the time being, and probably won’t switch the page to Columbus until July. If you’re interested in a full day of serious Core Audio hackery and slashery, save the date (Thursday, August 9), and start thinking about how you’ll get yourself to central Ohio.

Hope to see you there. I’m looking forward to being able to do a full day of Core Audio.

Times Change, People Change, Hairstyles Change… Security Changes

I’m getting a lot of hits on Sunday’s App Rejections Are A Lousy Way to Communicate Policy Changes, courtesy of a link from Daring Fireball, which is pretty magnanimous considering I kind of slam Gruber halfway through. That blog argued that suddenly rejecting apps for accessing the UDID is a terrible way to handle a policy change, that Apple’s usually far better about controlling the message, and that developers shouldn’t hear about this stuff from Twitter and TechCrunch.

Unfortunately, a lot of the conversation here and elsewhere has been hijacked by a focus on the UDID specifically and privacy issues in general, largely by uninformed readers who are quick to blame everyone who didn’t see this coming.

I’m going to use this blog to explain what the UDID is and the problems around it, from the POV of a developer who’s both chosen to use it and inherited code that uses it.

Take this with the grain of salt that I Am Not A Security Expert (IANASE), or perhaps I Am Not Graham Lee (IANGL).

What Is the UDID?

The Unique Device Identifier is exactly what it says on the tin: a long string of characters that uniquely identifies one iOS device. It only identifies the device, not the person using it (I believe it stays the same after a device wipe, but I don’t feel like wiping my iPad to test that). Any user can find his or her UDID by connecting their device to iTunes and option-clicking the Serial Number.

Since the first public SDK in iPhone OS 2.0, the UDID has been available to developers by calling -[UIDevice uniqueIdentifier]. The reason you would want to do so is typically to identify one instance of your app running in the wild, or perhaps as a stub to create other unique IDs (for example, a document-creating app that IDs each document as UDID plus the time it was created).

Imagine you want to know how often your users use your app. You could set up a URL to log startups, and then hit it from your app. But if you got 30 hits, you wouldn’t know if that was 30 devices running your app once, or one device running it 30 times. If each call sends the UDID, then you’d be able to tell.

So What’s The Problem

Most of us would agree that this scenario is pretty benign. And in fact, many apps gather a lot more metrics than this — what features are used most, which ones are used together, etc.

Let’s set aside for the moment of whether gathering usage metrics is OK (with or without the user’s permission). So far, this doesn’t seem bad. In fact, we still don’t know who’s running the app — no matter how much information we collect on a given UDID, all we know is that one device exists that is being used in that way.

Let’s say we have 9 apps that collect metrics like this, each phoning home metrics to the developer or some third-party’s server. Now what if a 10th app does the same thing, but it for some reason is able to collect personal information (maybe it’s subscription based, maybe it uses a Facebook login, whatever). That app is clearly able to correlate metrics to a given user. But since it shares the same UDID with the other 9 apps, we can now associate the activities in those apps with a specific individual.

Can you say “unintended consequences”? This is, as I understand it, the problem with the UDID, and why Apple has deprecated its use.

They Should Have Known!

No, the issue is that no one should have thought it was ok to use information that could identify or otherwise compromise another person’s privacy. It should have been obvious that once this got out Apple would need to do something about it. It should have been obvious that you should not have been doing it at all.

Icouldseeitcoming, commenting on App Rejections Are A Lousy Way To Communicate Policy Changes

My point in the above story is that the potential for misuse of the UDID does not come from the string itself. Remember, it conveys no personally identifying information. The problem has arisen over time, in an unexpected way, based on many apps working together (not necessarily with their explicit intent or permission).

Was Apple negligent in offering access to the string in the first place? All indications are that they actually gave privacy some serious thought as they developed the iPhone SDK. Consider the Address Book. No, not the Path debacle (we’ll get to that). Over on Mac OS X, there is a method called -[ABAddressBook me] (also the C function ABGetMe()) that returns the user’s address book card. In the C-based iPhone Address Book API, there is no equivalent call to get the user’s record. Clearly, Apple did put some thought into what third-party developers should and shouldn’t have access to, and decided that being able to personally identify the user of the phone was a bad idea. Despite benign uses this prevents, many of us would consider this a good decision.

So given that, let’s consider this absolutist position that “no one” should have thought it OK to use the UDID. Let’s just use Occam’s Razor: do we really believe that Apple, all the ad networks and analytics companies, and the majority of iOS developers are just stupid and negligent? That’s a huge pill to swallow. The alternative hypothesis — that the sense of what is and isn’t acceptable privacy policy has changed over the last four years, particularly in light of how things have actually played out among 700,000 apps — is far more plausible.

To that end, let me tell you another story…


Apple’s guidance in the iOS 5 deprecation statement for the -[UIDevice uniqueIdentifier] call is to generate a CFUUID and persist that in the NSUserDefaults. I’d be inclined to use the Keychain so it survives app deletion and reinstalls, but same difference. The upshot is, the one app that just needs to log app launches still has what it needs: a unique identifier of one instance of the app. When each app creates its own CFUUID, the 10 apps in our above example phone home with 10 different unique identifiers, so one can’t be used to compromise the identity of another. So far, so good.

So what is a CFUUID? It’s Apple’s C API for working with Universally Unique Identifiers (UUIDs). From Apple’s docs:

UUIDs (Universally Unique Identifiers), also known as GUIDs (Globally Unique Identifiers) or IIDs (Interface Identifiers), are 128-bit values guaranteed to be unique. A UUID is made unique over both space and time by combining a value unique to the computer on which it was generated—usually the Ethernet hardware address—and a value representing the number of 100-nanosecond intervals since October 15, 1582 at 00:00:00.

So that’s good, we can’t trace the IDs back to the… hey, wait a minute, what was that? Combining the network hardware address (aka, the MAC address) with the time the UUID was created? Doesn’t that mean that a group of UUIDs created on the same device would all have the same MAC address? So if you can get that MAC address out of the UUID, then even though the 10 apps that phone home 10 different UUIDs, we could get the MAC address that’s common to all of them, identify the user and we’re right back where we started! What the hell? Rabble! Rabble!

Well, as it turns out, Apple’s documentation is wrong. Look back at the Wikipedia entry again and notice that UUIDs have versions. The description above is for version 1, which was abandoned for exactly this reason:

This scheme has been criticized in that it is not sufficiently “opaque”; it reveals both the identity of the computer that generated the UUID and the time at which it did so.

Read in and we find that there is a version digit in the UUID, the character after the second hyphen. Now click to enlarge the screenshot below, from a sample app I showed at CocoaConf Chicago, and which generates hundreds or thousands of UUIDs a second in a (futile) search for duplicates:

UUID Starfield app - shows that iOS/OSX UUIDs are all version 4 and never duplicate

Notice that the digit after the hyphen is always a 4, meaning these are version 4 UUIDs, which are just really huge pseudo-random numbers, and therefore don’t reveal anything about who or what created them. Problem solved.

The reason I bring this up is that it was not at all “obvious” that putting the MAC address in the UUID was a bad idea, at least not so bad that it held up ratification of the standard (or, alternately, it wasn’t a problem until UUIDs started being used for purposes where revealing the creator’s identity was an issue). Lots of smart people worked on this stuff; it wasn’t thought to be a problem until later.

Like bugs, security problems are not things people create on purpose, and it’s insulting to insinuate that. They show up later, after reconsideration, after systems evolve, after third-party attacks.

You Want Evil? I’ll Show You Evil!

Yeah, you guys are right. How could anyone have expected that something called a “unique device identifier” might be used to track people.

Icouldseeitcoming, commenting on App Rejections Are A Lousy Way To Communicate Policy Changes

The UDID is neither necessary nor sufficient to track users. An app could use a hand-rolled UUID to track a device, as is Apple’s recommendation, and is in a position to log every tap and keystroke and phone it home to the analytics server. Heck, I had an AV Foundation demo a few years ago that encoded screen-grabs to a QuickTime movie — it wouldn’t take much more to provide a live video stream of a user’s interaction with my app back to an IP address of my choice, all without the user’s knowledge or assent.

That’s assuming I’m being evil on purpose of course. What removing the UDID hopes to improve is cases where apps inadvertently provide a way to correlate activity in different apps, which in turn could be linked to a real person if any of the apps capture personally-identifying information. Even now, there are other ways this could be done: apps could share hand-rolled UUIDs via URLs, document exchange, or the Keychain (if the apps were all signed with the same credentials and share a bundle id stub), though this requires a far greater degree of deliberate cooperation than the inadvertent UDID case.

There are other APIs with privacy implications too, such as free access to the Address Book (as epitomized by the Path case a few weeks back, and Facebook years earlier). An app that incorporates a UIWebView could also be vulnerable to any known Safari or JavaScript attack vectors. And whole apps are based around using Core Location to rat out your current location.

So to make a big deal out of the UDID as this obvious privacy problem seems badly ignorant. Its problematic aspects come from unintended consequences, not the nature of what it is.

And since any app can itself collect any information on your interactions with it, UDID or not, and phone it home with a network connection, the only perfect way to avoid being tracked at all is to go to the Settings application, turn on Airplane Mode, and never turn it off.

App Rejections Are a Lousy Way to Communicate Policy Changes

Following Twitter reports from earlier in the week, MacRumors and TechCrunch now report that Apple is rejecting apps that use the unique device identifier (UDID), by means of the -[UIDevice uniqueIdentifier] call.

This in itself is not surprising: iOS 5 deprecates the method, adding “Special Considerations” that advise developers to create a one-off CFUUID to identify a single install of the app on a single device.

So far, so good. I even had a section of my talk at last week’s CocoaConf Chicago that talked about CFUUIDs and the need to migrate any UDID dependencies to them now.

The problem is the timing. Apple’s established pattern has been to deprecate a function or method in one major version and, at the speediest, remove the call in the next major version. Many developers, myself included, expected that we had until iOS 6 to get off of the UDID.

But instead, without warning, the app review process is being used as an immediate death-penalty for the uniqueIdentifier call.

This is a problem because we’ve all had about six months to get off of UDID, and while that’s surely enough to get a simple app migrated — indeed, I have cases where switching it out is a 5-line fix — it is not necessarily the case that everyone can be expected to have already done this.

The real problem isn’t with developers; it’s with whom we develop apps for. Our clients don’t know or care what a UDID is, nor are they aware of a single line in Apple’s documentation saying “stop using this”. Sure, it’s our job to be on top of it. But let’s imagine apps with long development cycles — big apps, or academic apps that rev for the new school year in the Fall and are largely dormant the rest of the year. It’s entirely plausible and reasonable that developers of these apps have “get off UDID” as a high-priority item in their bug trackers, but are waiting for budget and approval to start working. And what if it’s not a simple process? What if an app has some deep dependency on access to the UDID, both in the app and on a server somewhere, meaning that two different teams are going to need to deal with losing access to uniqueIdentifier, and will need to come up with a plan to migrate user records over to a new id scheme?

Well, they just lost their chance.

Captain Hindsight is in full effect in the MacRumors forums, loudly asserting that developers should have known this was coming, have had plenty of time, etc. I get that it’s the natural defensiveness about Apple, but it gets worse… because this isn’t the only case of Apple using app rejections to carry out policy changes.

Thanks perhaps to my many posts about in-app purchase, I recently heard from a group of developers who’d gotten a galling rejection. They have an app with a subscription model, and used the new “auto-renewing subscription” product. This product is far superior to the original subscriptions that I have repeatedly described as broken, as they cannot restore between a user’s devices, and do not carry state to indicate what was subscribed to and when. Auto-renewing subscriptions fix these problems, and the In-App Purchase and iTunes Connect guides had (seemingly until a couple weeks ago), clearly disparaged use of the old subscriptions in favor of the new auto-renewing subscriptions.

So imagine the surprise of my colleagues when their app was rejected for using auto-renewing subscriptions. The reason given was that they were using it for a different business plan like a data-plan model, and auto-renewing subscriptions are, according to the reviewer, reserved only for content subscriptions like Newsstand magazines. I have never seen anything to this effect in any Apple I-AP documentation. Nevertheless, the developers had to switch to the shitty, broken, old subscriptions.

In both of these cases, we see Apple breaking with their own documentation or with long-established practice with no warning, and instead using app rejections as a tool to communicate and carry out new policies. This is wretched for developers, who get caught scrambling to fix problems they didn’t know they had (or didn’t expect just yet).

It’s also terrible for Apple, because the aggrieved developers initially control the message as they flock to blogs and Twitter, leaving it to loyalist commenters and bloggers like Gruber and the Macalope to mount a rear-guard gainsaying defense. To see Apple — of all companies! — not controlling the message is astounding.

All it takes is clarity. If they’re going to make such a major change, they’ve already got our attention via e-mails, the developer portal, and many other channels. They could and should clearly state the what, why, when, and how of policy changes. “We’re getting rid of UDIDs, because they constitute a privacy risk. We’ll reject any app that calls -[UIDevice uniqueIdentifier] as of March 23, 2012.” Not that hard. They’ve done it before: a few years back, Apple required streaming media apps to use HTTP Live Streaming if they streamed more than 10MB of data — this was communicated via announcements on the developer portal a month or so before its implementation, and nobody got caught by surprise, nobody complained.

Apple has developed a reputation for capriciousness in its app review process, and a cavalier attitude towards its developer partners. It’s not undeserved. As Erica Sadun once cleverly put it, “Apple is our abusive boyfriend.”

The Whiny Little Bitch Contingent meets iBooks Author

Let me introduce you to the “Whiny Little Bitch Contingent”. This was a term I coined in the late 2000’s to cover the Java developers who cried and moaned about the slow decline in Apple’s support for Java: the deprecation of the Cocoa-Java bridge, the long wait for Java 6 on Mac OS X, its absence from iOS, etc. Every time there was news on this front, they could be reliably counted on to dredge up Steve Jobs’ pledge at the JavaOne 2000 keynote to make the Mac the best Java programming environment… and to bring this up in seeming ignorance of the passage of many years, the changes in the tech world, the abject failure of Desktop Java, other companies’ broken promises (Sony’s pledge of Java on the PlayStation 2, the Java-based Phantom gaming console), etc.

The obvious trait of the Whiny Little Bitch Contingent is their sense of entitlement: companies like Apple owe us stuff. The more subtle trait is their ignorance of the basic principle that people, organizations, and companies largely operate in their own self-interest. Apple got interested in Java when it seemed like a promising way to write Mac apps (or, a promising way to get developers to write Mac apps). When that failed, they had understandably little interest in providing developers a means of writing apps for other platforms. I’m sure I’m not the only person to write a Java webapp on the Mac that I knew my employer would block Mac clients from actually using. By 2008, when Apple entered the mobile market with the iPhone, there was nothing about supporting Java that would appeal to Apple’s self-interest, outside of a small number of hardware sales to Java developers.

That’s what defines the WLBC to me: sense of entitlement, and an igorance of other parties’ self-interest (which leads to an expectation of charity and thus the sense of entitlement).

So, yesterday, Apple holds an event to roll out their whole big deal with Textbooks on the iPad. They look pretty, they’ve got an economic model that may make some sense for publishers (i.e., it may be in the publishers’ self-interest), etc. Also, there’s a tool for creating textbooks in Apple’s format.

And this is where the Whiny Little Bitch Contingent goes ape-shit. Because there’s a clause in the iBooks Author EULA that says if you’re going to charge for your books, you can only publish to Apple’s iBookstore.

So, let’s back up a second. The only point of this software is to feed Apple’s content chain. The only reason it is being offered, free, is to lure authors and publishers to use Apple’s stuff… which in turn sells more iPads and gives Apple a 30% cut. If you are not going to put stuff on Apple’s store, why do you even care about this? Hell, I don’t develop for Microsoft’s platforms, so if they see the need to turn Visual Studio into an adventure game… hey that’s their problem.

If you’re not authoring for Apple’s iBookstore, why do you even care what iBooks Author does, or what’s in its EULA?

In decrying the “cold cynicism” of Apple’s iBook EULA, Marshall Kirkpatrick writes:

It’s hard to wrap my brain around the cold cynicism of Apple’s releasing a new tool to democratize the publishing of eBooks today, only to include in the tool’s terms and conditions a prohibition against selling those books anywhere but through Apple’s own bookstore

“Democratize the publishing of eBooks”? Where the hell did he get that? Maybe he watched the video and fell for the grandiosity and puffery… I never actually watch these Apple dog-and-pony shows anymore, as following the Twitter discussion seems to give me the info I need. But thinking that Apple is in the business of democratizing anything is nuts: they’re in the business of selling stuff, and the only reason they’d give out a free tool is to get you to help them sell more of that stuff.

I didn’t download iBooks Author, even though you’d expect an Apple-skewing author like me to be one of the first onboard. Frankly, I’m pretty tired of writing, as the last two books have been difficult experiences, and the thought of starting another book, even with a 70% royalty instead of 5%, is not that appealing. A year ago I thought about self-publishing a book on AV Foundation, but right now I lack the will (also, I’ve failed to fall in love with AV Foundation, and blanch at its presumptions, limitations, and lack of extensibility… I much prefer the wild and wooly QuickTime or Core Audio).

So, if we’re going to talk about iBooks Author, let me know how it holds up for long documents: if it’s pretty on page 1, is it still usable when you’re 200 pages in? Does it offer useful tools for managing huge numbers of assets? Does it provide its own revision system and change tracking, or does it at least play nicely with Subversion and Git? Can it be used in a collaborative environment? These are interesting questions, at least to people who plan to use the tool to publish books on the iBookstore.

But if Apple’s not giving you a pretty, free tool you can use to write .mobi files that Amazon can sell Kindles with? Sorry, Whiny Little Bitch Contingent, I’ve got zero sympathy for you there. Call it a third party opportunity. Or just put on your big boy underwear and do it yourself.

Take it, Geddy:

You don’t get something for nothing
You can’t have freedom for free
You won’t get wise
With the sleep still in your eyes
No matter what your dreams might be

Achievement Unlocked: Finish “Learning Core Audio”

There’s nothing like losing your editor — to Apple, no less — to ratchet up the heat to finish a book that has been too long on the burner. But with Chuck doing exactly that at the end of December, Kevin and I had the motivation to push aside our clients and other commitments long enough to finally finish the Learning Core Audio book (yes, the title is new), and send it off to the production process.

In our final push, we went through the tech review comments and reported errata — Lion broke a lot of our example code — and ended up rewriting every example in the book as Xcode 4 projects, moving the base SDK to Snow Leopard, which allowed us to ditch all the old Component Manager dependencies. For the iOS chapter, we rev’ed up to iOS 4 as a baseline and tested against iOS 5.

One of the advantages of Xcode 4 is that the source directory is cleaner for source control (no more ever-changing build folder that you have to avoid committing), while also offering a pretty simple way to get to the “derived data” folder with the build result, which was important for us because we have a number of command-line examples that create audio files relative to the executable, and Xcode 4 makes them easy to find.

In our final push, we also managed to get in an exercise with the AUSampler, the MIDI instrument that pitch-shifts the audio file of your choice, into the wrap-up chapter. So that should keep things nice and fresh. Thanks to Apple for finally providing public guidance on how to get the .aupreset file to load into the audio unit, and how the unit deals with absolute paths to the sample audio in the app bundle case.

Updated code is available from my Dropbox:

From here, Pearson will take a few months to layout the book, run it by us for proofing and fixes, and send it off to the printer. So… paper copies probably sometime in Spring. The whole book — minus this last round of corrections — is already on Safari Books Online, and will be updated as it goes through Pearson’s production process.

It seems like there’s been a big uptake in Core Audio in the last year or two. More importantly, we’ve moved from people struggling through the basics of Audio Queues for simple file playback (back in iPhone OS 2.0 when Core Audio was the only game in town for media) and now we see a lot of questions about pushing into interesting uses of mixing, effects, digital signal processing, etc. Enough people have gotten sufficiently unblocked that there’s neat stuff going on in this area, and we’re fortunate to be part of it.

Five Years, That’s All We’ve Got

As mentioned before, I’m not a big fan of panels at developer conferences, and whenever I’m in one, I deliberately look for points of contention or disagreement, so that we don’t end up as a bunch of nodding heads who all toe a party line. Still, at last week’s CocoaConf in Raleigh, I may have outdone myself.

When an iOS developer in the audience asked if he should get into Mac development, most of the panel said “go for it”, but I said “don’t bother: the Mac is going to be gone in 5-10 years. And what’s going to kill it is iOS.”

This is wrong, but not for the reason I’ll initally be accused of.

First, am I overstating it? Not in the least. Just looking at things where they stand today, and the general trends in computing, I can’t see the Mac disappearing in less than five years, but I also can’t imagine it prevailing more than another 10.

This isn’t the first time I’ve put an unpopular prediction out there: in 2005, back when I was with O’Reilly and right after the Intel transition announcement, I I predicted that Mac OS X 10.6 would come out in 2010 and be Intel-only. This was called “questionable”, “dumb”, and “ridiculous advice”. Readers said I had fooled myself, claimed I was recommending never upgrading because something better is always coming (ie, a straw man argument), argued Intel wouldn’t be that big a deal, and predicted that PPC machines would still be at least as common as Intel when 10.6 came out. For the record, 10.6 came out in August, 2009 and was indeed Intel-only. Also, Intel Macs had already displaced PowerPC in the installed base by 2008.

So, before you tell me I’m an idiot, keep in mind that I’ve been told that lots of times before.

Still, punditry has been in the “Mac is doomed” prediction business for 20 years now… so why am I getting on board now?

Well, the fact that I’m writing this blog on my iPad is a start. And the fact that I never take my MacBook when I travel anymore, just the iPad. And the issue that Lion sucks and is ruining so much of what’s valuable about the Mac. But that’s all subjective. Let’s look at facts and trends.

iOS Devices are Massively Outselling Mac OS X

One easy place to go for numbers is Apple’s latest financial reports. For the quarter that ended Sept. 30, 2011 (4Q by Apple’s financial calendar), the company sold 4.89 million Macs, 11.12 million iPads, and 17.07 million iPhones. That means the iPad is outselling all models of Mac by a factor of more than 2 to 1.

The numbers also mean that iOS devices are outselling Mac OS X devices by a ratio of at least 5.7 to 1… and it must be much more, since Apple also sold 6.62 million iPods (since these aren’t broken down by model, we don’t know which are iOS devices and which aren’t).

While the Mac is growing, iOS is growing much faster, so this gap is only going to continue to grow.

Goin’ Mobile

Let’s also think about just which Macs are selling. The answer is obvious: laptops. The Mac Unit Sales chart in this April 2011 MacWorld article shows Apple laptops outselling desktops by a factor of nearly 3-to-1 for the last few quarters. Things are so cold for desktops that there is open speculation about whether the Mac Pro will ever be updated, or if it is destined to go the way of the Xserve.

Now consider: Apple has a whole OS built around mobility, and it’s not Mac OS X. If the market is stating a clear preference for mobile devices, iOS suits that better than the Mac, and the number of buyers who prefer a traditional desktop (and thus the traditional desktop OS) are dwindling.

Replace That Laptop!

Despite the fact that it’s only about 28% of Apple laptop sales, I would argue the definitive Mac laptop at this point is the MacBook Air. It’s the most affordable MacBook, and has gotten more promotion this year than any other Mac (when was the last time you saw an iMac ad?). It also epitomizes Apple’s focus on thinness, lightness, and long battery life.

But on any of these points, does it come out ahead of an iPad 2? It does not. And it costs twice as much. The primary technical advantage of the Air over the iPad 2 are CPU power, RAM, and storage.

Is there $500 worth of win in having bigger SSD options or a faster CPU?

Few People Need Trucks…

“But”, you’re saying, “I can do real work on a Mac”. Definitely true… but how much of it can you really not do on an iPad? For last month’s Voices That Matter conference, I wrote slides for two talks while on the road, using Keynote, OmniGraffle, and Textastic… the same as I would have used on my Mac Pro, except for using Xcode to work with code instead of Textastic. I also delivered the talk via Keynote off the iPad with the VGA cable, and ran the demos via the default mirroring over the cable.

I’ve gone three straight trips without the laptop and really haven’t missed it. And I’m not the only one. Technologizer’s Harry McCracken posted a piece the other week on How the iPad 2 Became My Favorite Computer.

Personally, the only thing that I think I’m really missing on my iPad is Xcode, so that I could develop on the road. I suspect we’ll actually see an Xcode for iPad someday… the Xcode 4 UI changes and its single-window model made the app much more compatible with iPad UI conventions (the hide-and-show panes could become popovers, for example). And lest you argue the iPad isn’t up to the challenge, keep in mind that when Xcode 1.0 was first released in Fall, 2003, a top-of-the-line Power Mac G5 had a dual-core 2.0GHz CPU and 512 MB RAM, whereas the current iPad 2 has a dual-core A5 running at 1.0GHz and 512 MB RAM, meaning iPad is already in the ballpark.

…and Nobody Needs a Bad Truck

“But Mac OS X is a real OS,” someone argues. Sure, but two things:

  • How much does that matter – a “real OS” means what? Access to a file system instead of having everything adjudicated by apps? I’d say that’s a defining difference, maybe the most important one. But it matters a lot less than we might think. Most files are only used in the context of one application, and many applications make their persistence mechanism opaque. If your mail was stored in flat files or a database, how would you know? How often do you really need or want the Finder? With a few exceptions, the idea of apps as the focus of our attention has worked quite well.

    What exceptions? Well, think of tasks where you need to combine information from multiple sources. Building a web page involves managing HTML, CSS, JavaScript, and graphic files: seemingly a good job for a desktop OS and bad job for iOS. But maybe it argues for a task-specific app: there’s one thing you want to do (build a web page), and the app can manage all the needed files.

  • For how long will Mac OS X be a “real OS”? – Anyone who follows me on Twitter knows I don’t like Lion. And much of what I don’t like about it is the ham-handed way iOS concepts have been shoehorned into the Mac, making for a good marketing message but a lousy user experience. Some of it is just misguided, like the impractical and forgettable LaunchPad.

    But there’s a lot of concern about the Mac App Store, and the limitations being put on apps sold through the MAS. This starts with sandboxing, which makes it difficult or impossible for applications to damage one another or the system as a whole. As Andy Ihnatko pointed out, this utterly emasculates AppleScript and Automator. Daniel Steinberg, in his “Mac for iOS Programmers” talk at CocoaConf, also wondered aloud if inter-application communication via the NSDistributedNotificationCenter will be the next thing to go. And plenty of developers fear that in time, Apple will prohibit third-party software installs outside of the MAS.

Steve Jobs once made a useful analogy that many people need cars and only a few need trucks, implying that the traditional PC as we’ve known it is a “truck”, useful to those with advanced or specific needs. And that would be fine… if they were willing to let the Mac continue to be the best truck. But instead, the creep of inappropriate iPad-isms and the iOS-like limitations being put on Mac apps are encroaching the advanced abilities that make the truck worth owning in the first place.

The Weight of the Evidence

Summarizing these arguments:

  • iOS devices are far outselling Mac OS X, and the gulf is growing
  • The iPad and the MacBook (the only Mac that matters) are converging on the same place on the product diagram: an ultra-light portable computing device with long battery life
  • iOS is already capable of doing nearly anything that Mac OS X can do, and keeps getting better.
  • Mac OS X shows signs of becoming less capable, through deliberate crippling of applications by the OS.

Taken together, the trends seem to me like they argue against the future of Mac OS X. Of the things that matter to most people, iOS generally does them better, and the few things the Mac does better seem like they’re being actively subverted.

Some people say the two platforms will merge. That’s certainly an interesting possibility. Imagine, say, an iOS laptop that’s just an iPad in a clamshell with a hardware keyboard, likely still cheaper than the Air, and the case for the MacBook gets weaker still.

Given all this, I think OS X becomes less necessary to Apple — and Apple users — with each passing year. When does it reach a point where OS X doesn’t make sense to Apple anymore? That’s what I’m mentally pencilling in: 5-10 years, maybe after one or two more releases of OS X.


But in the beginning, I said I was wrong to say that an iOS developer shouldn’t get into Mac programming because the Mac is doomed. And here’s why that’s wrong: you shouldn’t let popularity determine what you choose to work with. Chasing a platform or a language just because it’s popular is always a sucker’s bet. For one thing, times change, and the new hotness becomes old news quickly. Imagine jumping into Go, which in 2009 grew fast enough to become the “language of the year” on the TIOBE programming language index. It’s currently in 34th, just behind Prolog, ahead of Visual Basic .NET, and well behind FORTRAN (seriously!).

Moreover, making yourself like something just because it’s popular doesn’t work. As Desktop Java faded into irrelevance, I studied C++ and Flash as possible areas of focus, and found that I really didn’t like either of them. Only when the iPhone OS came along did I find a platform with ideas that appealed to me.

Similarly, I greatly value the time I spent years ago studying Jini, Sun’s mis-marketed and overblown self-networking technology. Even though few applications were ever shipped with it — Jini made the fatal mistake of assuming a Java ubiquity that did not actually exist outside of Sun’s labs — the ideas it represented were profound. Up to that point, I had never seen an API that presented such a realistic view of networking, one that kept in mind the eight fallacies of distributed computing and made them managable, largely by treating failure as a normal state, rather than an exceptional one. In terms of thinking about hard problems and how stuff works (or doesn’t work) in the real world, learning about Jini was hugely valuable to me at the time I encountered it.

And had I known Jini was doomed, would I have been better off studying something more popular, like Java Message Service (which my colleagues preferred, since it “guaranteed” message delivery rather than making developers think about failure)? I don’t think so. And so, even if I don’t think the Mac has a particularly bright future, that’s no reason for me to throw cold water on someone’s interest in learning about the platform. There are more than 20 years of really good ideas in the Mac, and if some of them enlighten and empower you, why not go for it?

Dude, Where’s My Archive?

Sometime last week, the archives at went dark, replaced by the ambiguous message:

Archives are currently disabled. If you require urgent access to the Archives, please contact with the subject “ARCHIVES”.

Apple’s developer mailing lists have been around for at least a decade, and contain a wealth of real-world knowledge, particularly on the many APIs that pre-date the establishment of Apple’s web-based Dev Forums a few years ago. While the lists themselves continue to operate and distribute new messages, the archives have been out since at least late last week.

For Core Audio, the loss of the archives is absolutely devastating. Everyone complains about the lack of documentation for Core Audio, but that’s not quite the problem. It’s that the nature of Core Audio is that the syntax is simple and the semantics are where the real work gets done. It’s very easy to create a AudioUnitSetProperty() call that compiles, and very difficult to create one that doesn’t crash and instead does something useful. That’s the good and the bad of an API whose favorite idiom is getting and setting void* properties; compare to AV Foundation, whose far more limited abilities can reasonably be gleaned by reading the docs.

When the nature of the framework is knowing what you can and can’t do with the various properties, what the audio engines will and won’t accept, and why the hell you’re getting OSStatus -50 (paramErr), the best resource you could hope for is 10 years of people doing the same thing and sharing their results. And now it’s gone.

What’s worse is that Apple, as ever, has provided far too little information for their partners to know where they stand or what to do. Are the archives down because of prolonged maintenance, like taking the tapes from Cupertino to North Carolina and hosting them there? Was there a database crash that is now being recovered from? Or was there a business or political decision to just shut down the archives indefinitely (imagine if, say, a legal rival was getting evidence against Apple from the listserv archives, or if Charlie Miller’s App Store security hack was based on information gleaned from the archives). The thing is, we don’t know whether or not to expect the archives to return, and as is so often the case, Apple isn’t being clear with us.

For now, we can complain. And file bugs against the site. Feel free to dupe mine from Open Radar.

Taking C Seriously

Dennis Ritchie, a co-creator of Unix and C, passed away a few weeks ago, and was honored with many online tributes this weekend for a Dennis Ritchie Day advocated by Tim O’Reilly.

It should hardly be necessary to state the importance of Ritchie’s work. C is the #2 language in use today according to the TIOBE rankings (which, while criticized in some quarters, are at least the best system we currently have for gauging such things). In fact, TIOBE’s preface to the October 2011 rankings predicted that a slow but consistent decline in Java will likely make C the #1 language when this month’s rankings come out.

Keep in mind that C was developed between 1969 and 1973, making it nearly 40 years old. I make this point often, but I can’t help saying it again, when Paul Graham considered the possible traits of The Hundred-Year Language, the one we might be using 100 years from now, he overlooked the fact that C had already made an exceptionally good start on a century-long reign.

And yet, despite being so widely used and so important, C is widely disparaged. It is easy, and popular, and eminently tolerated, to bitch and complain about C’s primitiveness.

I’ve already had my say about this, in the PragPub article Punk Rock Languages, in which I praised C’s lack of artifice and abstraction, its directness, and its ruthlessness. I shouldn’t repeat the major points of that article — buried as they are under a somewhat affected style — so instead, let me get personal.

As an 80’s kid, my first languages were various flavors of BASIC for whatever computers the school had: first Commodore PETs, later Apple IIs. Then came Pascal for the AP CS class, as well as a variety of languages that were part of the ACSL contests (including LISP, which reminds me I should offer due respect to the recent passing of its renowned creator, John McCarthy). I had a TI-99 computer at home (hey, it’s what was on sale at K-Mart) and its BASIC was godawful slow, so I ended up learning assembly for that platform, just so I could write programs that I could stand to run.

C was the language of second-year Computer Science at Stanford, and I would come back to it throughout college for various classes (along with LISP and a ruinous misadventure in Prolog), and some Summer jobs. The funny thing is that at the time, C was considered a high-level language. At that time, abstracting away the CPU was sufficient to count as “high-level”; granted, at the time we also drew a distinction between “assembly language” and “machine language”, presumably because there was still someone somewhere without an assembler and was thus forced to provide the actual opcodes. Today, C is considered a low-level language. In my CodeMash 2010 talk on C, I postulated that a high-level language is now expected to abstract away not only the CPU, but memory as well. In Beyond Java, Bruce Tate predicted we’d never see another mainstream language that doesn’t run in a VM and offer the usual benefits of that environment, like memory protection and garbage collection, and I suspect he’s right.

But does malloc() make C “primitive”? I sure didn’t think so in 1986. In fact, it did a lot more than the languages at the time. Dynamic memory allocation was not actually common at that time — all the flavors of BASIC of that time have stack variables only, no heap. To have, say, a variable number of enemies in your BASIC game, you probably needed to do something like creating arrays to some maximum size, and use some or all of those arrays. And of course relative to assembly language, where you’re directly exposed to the CPU and RAM, C’s abstractions are profound. If you haven’t had that experience, you don’t appreciate that a = b + c involves loading b and c into CPU registers, invoking an “add” opcode, and then copying the result from a register out to memory. One line of C, many lines of assembly.

There is a great blog from a few years ago assessing the Speed, Size, and Dependability of Programming Languages. It represents the relationship between code size and performance as a 2-D plot, where an ideal language has high performance with little code, and an obsolete language demands lots of work and is still slow. These two factors are a classic trade-off, and the other two quadrants are named after the traditional categorization: slow but expressive languages are “script”, fast but wordy are “system”. Go look up gcc – it’s clearly the fastest, but its wordiness is really not that bad.

Perhaps the reason C has stuck around so long is that its bang for the buck really is historically remarkable, and unlikely to be duplicated. For all the advantages over assembly, it maintains furious performance, and the abstractions then built atop C (with the arguable exception of Java, whose primary sin is being a memory pig) sacrifice performance for expressiveness. We’ve always known this of course, but it takes a certain level of intellecutual honesty to really acknowledge how many extra CPU cycles we burn by writing code in something like Ruby or Scala. If I’m going to run that slow, I think I’d at least want to get out of curly-brace / function-call hell and adopt a different style of thinking, like LISP.

I was away from C for many years… after college, I went on a different path and wrote for a living, not coming back to programming until the late 90’s. At that point, I learned Java, building on my knowledge of C and other programming languages. But it wasn’t until the mid-2000’s that I revisted C, when I tired of the dead-end that was Java media and tried writing some JNI calls to QuickTime and QTKit (the lloyd and keaton projects). I never got very far with these, as my C was dreadfully rusty, and furthermore I didn’t understand the conventions of Apple’s C-based frameworks, such as QuickTime and Core Foundation.

It’s only in immersing myself in iOS and Mac since 2008 that I’ve really gotten good with calling C in anger again, because on these platforms, C is a first-class language. At the lower levels — including any framework with “Core” in its name — C is the only language.

And at the Core level, I’m sometimes glad to only have C. For doing something like signal processing in a Core Audio callback, handing me a void* is just fine. In the higher level media frameworks, we have to pass around samples and frame buffers and such as full-blown objects, and sometimes it feels heavier than it needs to. If you’re a Java/Swing programmer, have you ever had to deal with a big heavy BufferedImage and had to go look through the Raster object or whatever and do some conversions or lookups, when what you really want is to just get at the damn pixels already? Seems to happen a lot with media APIs written in high-level languages. I’m still not convinced that Apple’s AV Foundation is going to work out, and I gag at having to look through the docs for three different classes with 50-character names when I know I could do everything I want with QuickTime’s old GetMediaNextInterestingTime() if only it were still available to me.

C is underappreciated as an application programming language. Granted, there’s definitely a knack to writing C effectively, but it’s not just the language. Actually, it’s more the idioms of the various C libraries out there. OpenGL code is quite unlike Core Graphics / Quartz, just like OpenAL is unlike Core Audio. And that’s to say nothing of the classic BSD and other open-source libraries, some of which I still can’t crack. Much as I loathe NSXMLParser, my attempt to switch to libxml for the sake of a no-fuss DOM tree ended after about an hour. So maybe it’s always going to be a learning process.

But honestly, I don’t mind learning. In fact, it’s why I like this field. And the fact that a 40-year old language can still be so clever, so austere and elegant, and so damn fast, is something to be celebrated and appreciated.

So, thanks Dennis Ritchie. All these years later, I’m still enjoying the hell out of C.

Speaking update and a Core Audio preview

Real life intervenes again (parsing PDF, whee!) and I have to cut short a planned epic iDevBlogADay entry. But I do want to bang out a few quick notes on various topics of interest.

Core Audio book coverThe first is Core Audio in iOS 5, which we can now talk about publicly. If we go through the iOS 4.3 to iOS 5.0 API Differences document, we see that Audio Units accounts for a large number of diffs. This comes from the addition of a suite of units that finally make programming at the unit level a lot more interesting. Whereas we used to get a single effects unit (AUiPodEQ), we now get high and low pass filters, the varispeed unit, a distortion box, and a parametric EQ that lets us play with sliders instead of the “canned” EQ settings like “Bass Booster” and “Spoken Word”. Even more useful, we get the AUFilePlayer, meaning you can now put audio from a file at the front of an AUGraph, instead of the sheer pain of having to decode your own samples and pass them to the AUGraph through a CARingBuffer.

iOS also gets the AUSampler unit introduced in Lion, which provides a MIDI-controlled virtual instrument whose output is pitch-shifted from a source sample. This was shown off at WWDC, although providing the source to the unit by means of an .aupreset is still a dark (undocumented) art. This is the first actual MIDI audio unit in iOS, which makes the presence of Core MIDI more useful on the platform.

Core Audio giveth, but Core Audio also taketh away: iOS 5 removes (not deprecates) VoiceIOFarEndVersionInfo. This struct, and its related constants (specifically kVoiceIOFarEndAUVersion_ThirdParty), were documented as interoperating with a hypothetical “3rd-party device following open FaceTime standards”, something I took note of last May as possibly meaning that FaceTime was still ostensibly being opened up. With the removal of these APIs, I think that closes the book on Apple having any intention to live up to its vow to publish FaceTime as an open standard.

There’s lots more to talk about, but I’m already over my allotted blogging time, and work beckons. Perhaps you’d like to hear me speaking about this stuff and demo’ing it? I’m doing an all-new-for-iOS-5 Core Audio talk at two upcoming conferences:

I’ll also be doing a talk about AV Foundation capture at these conferences. And back on audio, I just heard from my editor that the last three chapters of Core Audio should be in the Rough Cut on Safari Online Books in the next week or so, although I still have some work to do to clean up bits that are broken on Lion (read the sidebar on Audio Components if you’re having a problem creating audio units with the old Component Manager calls) and to clear out forward references to stuff that didn’t end up making the final cut for the book.

What Xcode 4 gets right (and Lion doesn’t)

It’s been a busy year for Apple user outrage, with radical changes to Xcode 4 and Final Cut Pro X provoking serious anger and lots of bitter denunciations on forums, blogs, Twitter and the like.

I can’t speak for Final Cut Pro X (I have yet to get my video hardware up to snuff), but frankly, I think Mac OS X 10.7 (Lion) deserves a lot more hate than Xcode 4.

And I’m happy to provide it.

Both have bugs, and with massive development, that’s not that surprising. I crash Xcode every few days. I get the spinning pinwheel of death from Lion every couple hours, in situations where it never occurred in Snow Leopard or earlier OS X releases. These will get smoothed out in time.

But once they are, what remains? Let me state my premise clearly: I like Xcode 4 because it’s built atop some fundamentally good ideas, and I dislike Lion because it’s not.

Let’s start with Xcode 4. Being on Lion, I can’t run Xcode 3 to reacquaint myself with the old days, but a few screenshots reminded me of some of its traits.

Xcode 3’s main window had a “Groups and Files” list on the left side. Except it didn’t have just files and groups of them. It also had an icon to represent your source code repository. And your recent searches. And smart searches. And bookmarks. And… you get the idea.

And that was before iPhone. Now Xcode had to handle provisioning, device management, remote debugging, archiving, and so on. iPhone development made demands that Xcode wasn’t really meant to handle, and it’s clear that iOS is going to be more and more important in the future, meaning that Xcode needs to be at least as aligned to iOS development as Mac, if not more so.

And this, to me, is what Xcode 4 gets right: it is a fundamental rethink of Xcode, informed by the first few years of iOS development. Its changes are radical, but in general, they’re based on cohesive and sensible ideas.

The biggest change in Xcode is how responsibilities are divvied up: the project workspace window is the container for anything related to a given project, and the organizer is for cross-project concerns like documentation, device management, source code repositories, and so on. Within the project workspace, there’s a fundamental left-to-right flow of specificity: a selection in the navigator sets the content area, and a selection in the content area can have further consequences in the utility area. That means we can pick files in the file navigator to bring them up in the source editor (the typical case), or use the log navigator to show build or runtime logs in the content area. The generic approach to the content area also opens up new opportunities: we already see this with Interface Builder incorporated as the editor for NIB files, and in Xcode 4.2, the content area offers up a new UI for editing storyboards.

Meanwhile, the now-prominent organizer makes the system of archiving builds more visible, which is critical not only because you now have to use this interface to submit to the App Store, but also because archiving is the only way to symbolicate and thereby make sense of crash logs you get back from Apple.

Quibble with specifics, or the roughness of a new codebase, but I do think Xcode 4 has its head in the right place. It’s built on fundamentally good, forward-looking decisions that put an end to the era in which Xcode frantically shoehorned in new iOS-related concepts, and is better positioned to adapt to whatever Apple throws at it over the next few years.

For a contrast, let’s look at Lion.

As with Xcode, I’ll set aside the annoying bugs — though I don’t know that I’ll ever forgive Lion’s Finder for losing the positioning of icons in most of my windows — and look at the ideas behind it.

What is the underlying concept of Lion? We’ve heard a lot about the importation of iPad features, notably the aggressive use of multi-touch gestures. The big one of these, of course, is the reversing of the scroll direction, dubiously spun as “natural” scrolling by Apple.

The problem with the iPad metaphors, for a start, is that there’s a fundamental difference between desktop and tablet gestures: desktop users are touching a proxy object like a magic mouse or trackpad. On the tablet, you can see the thing you’re touching; on the desktop, there’s a detach between the two.

In many ways, Lion seems optimized for laptops, which always have touchpads, and which enjoy a more intimate relationship with the user than a potentially sprawling desktop. As much as I hear the Mac Pro disk thrashing and see the aforementioned spinner, I also wonder if Lion isn’t really meant for use on machines with SSD storage instead of conventional hard disks.

And if Lion truly is optimized for portables, and if this is the reason for its seeming “iPad-ization”, I think it begs the question: why turn my Mac into an iPad, when I could just buy an iPad instead.

Honestly, I like my iPad. As I’ve said before, I like the iPad more than a laptop, and have gone iPad-only for my last few conferences. Thinking further ahead, the iPad is only going to get more powerful and more capable, while the traditional computer is fairly static in its abilities. Of all the things I need to do, the only productivity that’s really unavailable to me on the iPad is coding: there’s no Xcode for iPad, and it’s not clear whether a slimmed-down version would be possible with current hardware. But it’s not out of the question: Apple introduced Xcode in 2003, and the iPad 2 already outclasses a top of the line PowerBook of that era. In time, and probably not long from now, I’ll be able to do everything I care about on the iPad, and will be happy to.

So why compromise the desktop now, and turn it into something it’s not, which is to say a desktop OS with iPad features bolted on? Lion’s iPad-isms don’t really pay off for me, and what we’re left with is a mish-mash of incongruous concepts. Unlike Xcode 4, there’s no unifying concept behind Lion’s changes; instead, it feels like they’re trying to capture the iOS buzz and excitement, cramming in iPad-isms wherever they can be made to fit.

Steve Jobs famously made the analogy that desktop computers are like trucks, and that fewer and fewer people need trucks. It’s a clever and insightful analogy. The problem for me is that the people who need trucks don’t want those trucks turned into oversized sedans. What consistent ideas are present in Lion serve to work against what makes a desktop OS useful and productive in the first place.

The desktop OS doesn’t need a fundamental rethink; it may well be on a slow path to obsolesence, and it’s fine for Apple to let it go, as iOS is the heir apparent. But in lieu of a grand reinvention that is not likely, necessary, or needed, change for the sake of change is not welcome.

And don’t even get me started about the little things (monochrome icons in Finder sidebars, the hiding of ~/Library, Launchpad… must resist urge to hurt someone…)