Introducing Curtain

I’m excited to introduce Curtain to you today. Curtain is a packaging and deployment engine for desktop-like web apps; Curtain handles the business of generating the app from source files and deploying it on the server such that it supports offline use.

Curtain can be cloned from BitBucket, and it has a sample app, both under the BSD license. Rather than repeating the Readme found there, I would like here to provide some background.

Some background…

Offline support

I wanted to use Application Cache for a project; as you know, Application Cache is a douchebag, but even that article did not prepare me for how much of a douchebag it is. In particular, you want web apps to be able to be updated, if only because the first version inevitably has bugs. Remember that, even if the list of files in the manifest does not change, the manifest has to change whenever the app changes, otherwise users won’t get the updated version. So how to update the manifest and app?

  • If the app is updated in this manner:

    1. manifest is updated
    2. remainder is updated

    or even if the two are updated at the same time, then you could run into the following scenario:

    1. user does not have the app in cache, and fetches the HTML resource
    2. manifest is updated
    3. remainder is updated
    4. due to a network hiccup on her side, user only now fetches the manifest

    Now the user has the manifest for the updated version, but is really running the previous version of the web app. Even if the list of cached files is still correct, now whenever the user agent checks for an updated manifest it will find it to be bit-for-bit identical, and the user agent will not update the version the user uses, which is out of date, until a second update occurs. This is obviously not acceptable, and if the list of cached files is incorrect for the version it will be even worse.

  • Now imagine the web app is updated in this manner:

    1. remainder is updated
    2. manifest is updated 30 seconds (one network timeout) later

    In this case, the scenario in the previous case cannot occur: if the user fetched the HTML resource prior to the update, the user agent will either succeed before the manifest is updated, or will give up at its network timeout. However, another scenario can now occur:

    1. remainder is updated
    2. user loads the app from the server (either initial install or because he still had a version prior to the one before the update), both app files an manifest
    3. manifest is updated

    In that case, the user has the updated app but the manifest for the previous version. Even if the list of cached files is correct, the versions are inconsistent which is an issue if the new version turns out to have a showstopping issue (which sometimes only becomes apparent after public deployment, due to the enormous variety of user agents in the wild) and we decide to roll back to the previous version: in that case, whenever the user agent checks for an updated manifest, it will find it hasn’t changed and the user will keep using the version of the app that has a showstopping issue. When performing the rollback, we could decide to modify the manifest so that it is different from both versions, but this is dangerous: when rolling back you want to deploy exactly what you deployed before, in order to avoid running into further issues. And I don’t need to tell you how problematic having inconsistent app and manifest would be if the list of resources to cache changed during the update.

So how does Curtain solve this problem?

By updating the manifest twice:

  1. manifest is updated with intermediate contents
  2. remainder is updated
  3. manifest is updated again 30 seconds (one network timeout) later

If the list of resources to cache changes during the update, the manifest contains the union of the files needed by the previous version and the files needed by the updated version; and in all cases, the intermediate manifest contains in a comment two version numbers: the one for the app prior to the update, and the one for the app after the update. That way the manifest is suitable in both cases, and his method of update avoid all the issues associated with the previous methods.

Of course, that would be tedious and error-prone to handle by hand, so Curtain generates both intermediate and updated manifests from a script.

Versioned resources

I enjoy reading Clients from Hell; even though I don’t design web sites for a living I relate strongly to these horror stories. Except for one kind: those where the client complains he should not have to clear the cache/do a hard reload/etc. to see the fully updated site. Sorry, but for those, I side completely and unquestioningly with the client. Even in a development iteration context, it is up to the developer to show he can change the site and have the changes propagate without the user needing to do anything more than a soft reload (which invalidates the initial HTML resource if necessary, but nothing else), because such changes will need to happen in a post-deployment context. And don’t get me started on the number of site redesigns where the previous versions of all assets (icons, previous/next arrows, etc.) are still visible, and the announcement post starts with the caveat that you may have to reload manually in order for the redesign to be fully in effect… and even then, it has to be done again on a second page, because the main page does not have a “next” arrow for instance.

Yes, clearly you want resources and image assets, in particular, to be far-expire in order to save on bandwidth. But this means they must also be immutable: they might disappear, but may never, ever change; and if a different resource is needed, then it must have a different URL. Period.

Obviously, changing the resource name by hand, especially if you need to do so for every development iteration, is tedious and error-prone. When I read in web development tutorials, including some Application Cache ones, the suggestion to use, say, script-v2.js and increment version numbers that way, I can’t help but think “Isn’t that the cutest thing? Thinking you can do so flawlessly without ever forgetting to so do whenever a resource changes? Awwww…” because that is a recipe for failure, even if you only change these resources as part of a deploy.

Such inconsistency issues are even worse for offline web apps. Indeed, if your web app cannot work offline, you can just assume that, if your web app works incorrectly because of an inconsistent set of resources, the user will just reload and she will eventually get consistent resources. But in the case of an offline web app, once the user is back to her new home for which DSL hasn’t been installed yet (I’m getting tired of the airplane example) she has no opportunity for reload.

Even worse, even if the user checked while she was online that the web app was working correctly (which is asking a lot of her already), it may in fact be the previous version that was reloaded from the cache, while an inconsistently updated version is being downloaded, and when she relaunches it while at home she will get the inconsistent version. You can’t afford to be careless with offline web apps.

Curtain resolves this issue by relying on a version control system. On the build machine, all resources must be under a version-controlled work area, and Curtain will query the version control system for the ID of the version where the resource was last updated, and will generate a resource name by appending this version ID. Note that by doing it this way, Curtain will avoid changing the URL of the resource (which would invalidate it in the cache) even if everything else has changed, as long as the resource itself hasn’t changed. Curtain will process your HTML to replace references to the resource by references to the versioned resource name, and upload the result, and upload the resources themselves so that they have the versioned name on the server.

Curtain will also assign a version to the app as a whole, this is in particular put in a comment in the manifest (see above): this version is simply the current version of the version control system work area. Curtain itself must be in such a work area, so that if Curtain is updated but the source files are not, the version number is changed.

As part of these tasks, Curtain will manage the Cache-Control headers by synthesizing the necessary .htaccess file, which is especially important when using Application Cache; since it has to deal with .htaccess anyway, Curtain will also directly manage the MIME type of these resources, to avoid relying on the default Apache behavior (based on file extensions).

No progressive rendering

I have always found progressive rendering to be unsightly. It was necessary in the first days of the web, what with images taking seconds to download, it is largely necessary on mobile to this day, and it is still desirable on desktop for online apps. But for offline, desktop-like web apps? No way.

Curtain opts out of progressive rendering by downloading all dependent resources through XMLHttpRequest and explicitly loading the content, for instance for image resources by generating a URL for the downloaded Blob and assigning it through code to the src attribute of the img tag; this means Curtain-deployed web apps depend on XHR2 and Blob as a XHR responseType. Curtain will hide the interface until all resources have been loaded and assigned, assuming that the user will retry loading the app if no interface appears after a time; it is safe to assume the user is online at that time, because if he is offline, this means all the files listed in the Application Cache manifest are locally available and so will not fail to load.

If JavaScript is disabled or the browser does not have the necessary support for Curtain, we want to be able to show a message to that effect, and we want to do it in the context of the “usual” interface, so that she recognizes the web app. So the entirety of the interface is put in a div belonging to a CSS class called curtain. A small bit of JavaScript code before the interface hides this div: if JavaScript is disabled, the interface simply won’t be hidden. Then code after the interface will check everything necessary for the Curtain runtime to perform its job (using Modernizr in particular); if not everything is available, then the message will be changed and the div will be made visible.

The HTTP URLs of the images are put in the src attributes of the img tags in the initially downloaded HTML. However, this is only a provision for the above two error cases; in normal usage they will have been replaced by the blob URLs prior to the interface becoming visible.


First, Curtain generates static sites, and does not depend on any server programming language or any kind of server processing. Second, while early versions of the build and upload script were written as a shell script, Curtain is written in Python so as to be as portable as possible (it was that or Perl; I chose Python), though I have not been able to test it on Windows or Linux yet.

Third, Curtain embeds a bit of JavaScript code along with your app, and it expects your app to be written in JavaScript. However, Curtain makes no pretense at bringing JavaScript framework features; you should be able to use it with any JavaScript framework, including Vanilla JS.

Stay tuned…

Stay tuned, because tomorrow I will present you the sample app for Curtain, and its justification.

On the recent Apple top management adjustments

Michael Tsai summed up my thoughts exactly on the Schiller side of the announcements: I share his reservations about Schiller, but I indeed can’t complain when the various groups that interact with developers, whose lack of coordination I previously listed as being part of the problem, are now under a single top executive (with the exception of APIs, still the responsibility of Craig Federighi, of course).

So I thought I’d also mention the promotion to top leadership of Johny Srouji, promotion which to me represents the rise of semiconductor engineering inside Apple. Far from shedding this skill (as it might have appeared to some at the time of the Intel transition), Apple doubled down on it: in the domain of system glue (chipsets), peripheral controllers, sensors, etc., but also going as far as to design its own processors, both at the RTL level (with the acquisition of PA Semi) and at the RTL to mask translation level (with the acquisition of Intrisity); something Apple never did (as far as we know, anyway) for 68k, PowerPC, or any other processor they used prior to ARM. With impressive results, particularly now with the iPad pro.

The Mac App Store and long-term app preservation

I am fortunate enough not to have apps on the Mac App Store, and I have bought few enough apps on it (for reasons I previously exposed) that I initially missed the meltdown, due to the store, of many apps bought there. This is not an outage, in the sense that an outage implies the user is aware on some level on being dependent on an online resource; this is worse. This is not just unacceptable: this is a fundamental violation of the trust that both app developers and customers have placed in Apple, namely that bought, installed and compatible apps would keep working (short of any dramatic action taken for consumer protection so that they would not, such as revoking the certificate of a malicious developer).

Worse, this has implications beyond the Mac App Store per se. As you know, Apple is reserving many APIs related to online services even in a remote fashion to Mac App Store apps: even when there is a non-Mac App Store version of the app available, it cannot make use of iCloud (is there a typo version of “revealing tongue slips”? Because I initially typed ”iCould”…) or Apple Maps. So, in turn, how am I supposed to trust iCloud or Apple Maps, if I am not sure I can run any app that can access it? As if these services did not already have a reputation…

But even more troubling are the implications for long-term usage and preservation of software and it data. The consumer issue of not being able to trust that a purchased app will keep running even when nothing else changes is bad enough (you could set back the system clock, but how realistic is that, even in an unconnected system? You would no longer be able to trust the creation or modification dates of any of your documents, for a start); but the implications on being unable to preserve running software on a cultural level is frightening. Even more so for the documents with proprietary formats created by that software. I’ve been following with interest the initiatives of Jason Scott in that area, I am definitely down with the need to preserve this software and data, not just for ourselves, but the future generations. And the Mac App Store (and the iOS App Store, the only difference being that we have not had any fire drill on that side. Yet.) is “not helping”. To put it mildly, because this blog tries to be family friendly.

I initially though there was no DRM component to this story: certificates, “damaged apps”, that sounded like code signature infrastructure, in other words protection of the consumer against malware, something that the user can disable (ostensibly, at least). But when I tried to convince my Mac to run this app as an unsigned app, I encountered what is extremely likely to be the store DRM: I initially got the “your app was bought on another machine” message, so I tried deleting the receipt, but then I got the dreaded “app damaged” message, at which point I removed the signature. But no way: in that case, what happens is that the app does not launch either, with the console printing:

13/11/15 15:36:23,608 ([0x0-0x2cc2cc].com.tapbots.TweetbotMac[9317]) Exited with code: 173
13/11/15 15:36:23,663 storeagent: Unsigned app (/Applications/

Since I removed the MAS receipt, how is storeagent getting involved? Probably in order to decode the app DRM, and as you see it refuses to do so due to the app being now unsigned. So now we have DRM preventing us from running our legitimately bought software. I have kept a pristine copy of the app in a safe location to make further attempts, but the only way I can see is to create a new root CA which I install on the machine as a trusted root, and redo the signing chain, and even that might not work if the DRM is somehow tied to the signature chain.

I was already wary of buying apps without trials; this event guarantees that I will never buy anything else from the Mac App Store (and will try to obtain direct licenses of apps already bought there). No direct version of your app? You don’t get my business. I would delete the Mac App Store app if I could. Apple could change my mind by providing verifiable commitments on the ability to disengage the signature checks and in operational service levels, and even then… Furthermore, Apple owes an apology to all the app developers who trusted them with the Mac App Store and who had a long day (and will continue to have long days) of customer support entirely due to Apple’s incompetence.

Apple later on sent emails to developers to explain themselves on the issue; I will count that as the aforementioned apology. I don’t mind that they took a few business days to react, as they themselves had to figure out what the problems were from the multiple reports; I do mind that, operationally, they allowed developers and themselves to be caught flat-footed in the first place: why isn’t there anyone at Apple checking that a sample of Mac App Store apps do run on a machine with the time perpetually set to one month in the future? Still, I guess I’m glad we got an answer in the first place. — November 19, 2015

~ Reactions ~

Rainer Brockerhoff, besides presenting some investigations and corrections, took some issue with my investigation methods, and we started exchanging in the comments there. Don’t miss it.

Exercising, Apple TV and the Web

At the time of the initial discovery of its SDK, then again now with its recent release, debates have sparked about the presence of a web browser on the “new” (as of 2015) Apple TV, or to be more accurate about the lack thereof. And on the desirability of a web browser on a TV in general. I wish to contribute but one data point to the debate.

For two years now I have been keeping shape by using an elliptical/cross trainer for about an hour three times a week, among other purposes in order to be in shape when doing a week-long mountain trek in the summer. Which has led to looking for ways to fill these hours with some sort of distraction, and unfortunately (most) movies are not appropriate, given that, when combined with the exercise, they tend to make my heart rate go way too high. I did watch a number of works (humor in particular: Monty Python, Blackadder, Kaamelott , Spaceballs, etc.) but also tried alternatives, such as browsing the web, in order to catch up/read from the beginning some webcomics for instance. I tried three ways to do so:

  • attaching my iPad 2 to the trainer using a GorilaPod case (works very well, very much recommended!) and browsing the web with it,
  • using my iPhone as a mouse with Mobile Mouse Remote 1 (recommended too, if you need this kind of functionality) to control Safari running on my Mac,
  • using my Wii, connected to the same computer monitor, and its remote to control the built-in browser.

In the end, except for one aspect which ended up breaking the deal the supposedly terrible Wii browser actually provided the best experience. Indeed, in this constrained environment (remember I have to be holding the handlebars most the time) the Wii remote was the best way to interact, as I could actually hold it, and press the dpad to scroll, while still holding the handlebars, which was not the case with either other method; even when I occasionally had to point the remote (and thus let go of the right handlebar) this was surprisingly usable; moreso, I felt, than using the iPad.

The deal breaker was that the Wii was just way to slow to load and render pages. Any time I gained from its better interface was lost waiting each time for the page to appear. I have returned to mostly watching videos while training. It remains: other than speed, the meant-for-tv browser of the Wii was actually the best web browsing experience I could get while using a trainer.

Now imagine using the new Apple TV instead in this situation. It would simply not have the same kind of speed issue, obviously, and the Apple TV remote could potentially provide an even better experience, for instance by eschewing the pointer (as the Apple TV appears to be doing in general), the interaction with the touch surface on the remove performing both the scrolling and moving the focus from link to link instead; the + and – buttons would zoom in and out, etc. and all of it could be done without ever letting go of the handlebars.

Is it a common case? No, certainly not. Training, and in particular the person who trains being able to monopolize the device to which the Apple TV is connected, is a very specific use case. But it is a non-trivial, non-contrived use case in which remote-based, big screen web browsing makes perfect sense. So maybe the lack of a browser on the Apple TV is less a case of lack of floppy drive on the iMac, and more a case of lack of copy and paste on the original iPhone. I can only hope it eventually shows up, at least.

  1. Interestingly, I used that app from first trying out the “lite” version, then upgrading the the paid version; and I initially (re-)tried the lite version because I still had it installed from back when I tried it out as part of the “try before you buy” featured group, which you might remember I mentioned back in the day, so you see, you never know when someone installing and trying out the demo of your app might bear fruit!

Various comments on the iPad pro, among other Apple announcements

As someone who regularly expresses himself on how the iPad is (or how it currently falls short of being) the future of computing, I guess I should comment on the announcements Apple made this September, in particular of course the iPad pro. I think it’s great news, of course. But… where to begin? More so than the iPhone, it is software applications, and specifically third-party software, that will make or break the iPad, even more so for the iPad pro, considering that most of its hardware improvements will only really be exploited with third-party apps: it does not appear that Apple will provide a built-in drawing app to go with the impressive tablet drawing capabilities of the iPad pro, for instance.

And so, what corresponding iOS platform news did we get from Apple this September? Err, none. From a policy standpoint, iOS is still as developer-unfriendly, by not supporting software trials for instance, even though this is a fundamental commercial practice; in fact, this appear to be backfiring on Apple, as this resulted in potential buyers going for the already established brands1 when it comes to professional iPad software, and in Apple coming to bringing Adobe and Microsoft on stage in the presentation to prove the professional potential of the iPad pro; those two companies are probably the ones Apple wishes to be least dependent upon, and yet here we are.

And what about iOS, iOS 9 specifically? When it was announced at WWDC, my thoughts were, on the timing: “It’s about time!”, and on the feature set: “This is a good start.”; and this was in the context of the 10′ iPad, so with the iPad pro announcement I was expecting more multitasking features to be announced along with it, but nope, that was it, what I saw at WWDC and thought would be catching up, meant for the then-current iPads, was in fact a stealth preview of software features meant to be sufficient for the iPad pro. Don’t get me wrong, on-screen multitasking on the iPad is awesome (I’ve been playing with it this summer with the developer betas), but the iPad pro will need more than that. Much more, such as, I don’t know, drag and drop between apps? Or a system where one app could ask a service of another other app (bringing it on the screen by the first app’s side if it wasn’t present), similar to extensions except it would better use the screen real estate allowed by the iPad and iPad pro?

So yes, most definitely count me in with those who think Apple is solving only one part of the problem of the iPad platform with the iPad pro. I’m afraid the iPad has too little direct competition for Apple to take this problem seriously right now, and later it may be too late.

All that having been said, I am very impressed with what they’ve shown of the iPad pro’s capabilities as a graphic tablet, even if I will probably never use these capabilities myself; I think Wacom should indeed be worried. One thing that will matter a lot, but Apple hasn’t talked about or posted specs on, is the thinness of the so-called air gap between the screen and the drawing surface, which (along with latency, which they did mention in the keynote) makes all the difference in making the user feel like he is actually drawing on a surface, rather than awkwardly interacting with a machine; Piro of Megatokyo posted about this a while ago. This is something Apple has been good at, at least when compared with other handset/tablet makers. At any rate, the iPad, even the iPad pro, has to support the needs of everyone, so Wacom and other graphic tablet makers may still be able to differentiate themselves by providing possibilities that a tablet that still must support finger input and other usage patterns than drawing could not provide.

Lastly, I am interested in the iPad pro as a comic reader. The 10′ iPad family is generally great for reading manga and U.S. comics, as that screen size is large enough to contain a single page of them (in the case of U.S. comics, pages are actually slightly scaled down, but that does not impair reading), however it falls short when needing to show a double page spread, such as the (outstanding) one found in the latest issue of Princeless (if you’re not, you should be reading Princeless. Trust me.) or the not less outstanding ones found in Girl Genius. The iPad pro has the perfect size and aspect ratio for those, being able of showing two U.S. comics pages side by side at the same scale a 10′ iPad is able of showing a single page. A 10′ iPad is also too small to reasonably display a single page of comics of the French-Belgian tradition (aka “bandes dessinées”), while the iPad pro would be up to the task with only a minor downscale; I’m not about to give up buying my French-Belgian comics on paper any time soon, but it would be a wonderful way to read them for someone overseas who is far away from any store that distributes such comics, especially for less well-known ones.2

As for the other announcements… I don’t know what the new Apple TV will be capable of outside the U.S., so most of its appeal is hard to get for me. I have little to comment on with regard to its capabilities as an app platform, except that I find the notion of Universal iOS/tvOS games (even more so saved game handoff) to be completely ludicrous: the two have completely different interaction mechanisms, so the very notion that the “same game” could be running on both is absurd.

As for the iPhone 6S/6S+, what is to me most interesting about them is 3D touch and live photos. Those two are very dependent on the concept catching on with developers (well, Vine is ready for live photos, of course…): there is little point in being able to capture live photos if you can’t share them as such on Facebook/Flickr/Dropbox/etc., and it remains to be seen which developers will add 3D touch actions to their apps, and what for. So will they catch on? We’ll see.

  1. And they, in turn, have the branding power to pull off alternate payment schemes such as subscriptions, allowing them to thrive on the iPad more than developers dependent on race-to-the-bottom iOS App Store revenue do.
  2. What about double page spreads in French-Belgian comics? Those are rare, but they exist, most notably in the œuvre of Cabu (yes, that Cabu). However, I am not sure the 17′ handheld tablet that would be necessary to properly display these would be very desirable.

Maybe Android did have the right idea with activities

One of the features that will land as part of iOS 9 is a new way to display web content within an app by way of a new view controller called SFSafariViewController, which is nicely covered by Federico Viticci in this article on MacStories. I’ve always been of the (apparently minority) opinion that iOS apps ought to open links in the default browser (which currently is necessarily Mobile Safari), but the Safari view controller might change my mind, because it pretty much removes any drawback the in-app UI/WKWebView-based browsers had: with the Safari view controller I will get a familiar and consistent interface (minus the editable address bar, of course), the same cookies as when I usually browse, my visits will be registered in the history, plus added security (and performance, though WKWebView already had that), etc. Come November, maybe I will stop long-tapping any and all links in my Twitter feed (in Twiterrific, of course) in order to bring the share sheet and open these links in Safari.

Part of my reluctance to use the in-app browsers was that I considered myself grown up enough to switch apps, then switch back to Twitter/Tumblr/whatever when I was done with reading the page: I have never considered app switching to be an inconvenience in the post-iOS 4 world, especially with the iOS 7+ multitasking interface. But I understand the motivation behind wanting to make sure the user goes back to whatever he was doing in the app once he is done reading the web content; and no, it is not about the app developers making sure the user does not stray far from the app (okay, it is not just about that): the user himself may fail to remember that he actually was engaged in a non-web-browsing activity and thus is better served, in my opinion, by a Safari experience contained in-app than he is by having to switch to Safari. For instance, if he is reading a book he would appreciate resuming reading the book as soon as he is done reading the web page given as reference, rather than risk forgetting he was reading a book in the first place and realize it the following day as he reopens the book app (after all, there is no reason why only John Siracusa ebooks should have web links).

And most interestingly, in order to deliver on all these features, the Safari view controller will run in its own process (even if, for app switching purposes for instance, it will still belong to the host app); this is a completely bespoke tech, to the best of my knowledge there is no framework on iOS for executing part of an app in a specific process as part of a different host app (notwithstanding app extensions, which provide a specific service to the host app, rather than the ability to run a part of the containing app). And this reminded me of Android activities.

For those of you not familiar with the Android app architecture, Android applications are organized around activities, each activity representing a level of full-screen interaction, e.g. the screen displaying the scrollable list of tweets complete with navigation bars at the top and/or bottom, with the activity changing when drilling down/back up the app interface, e.g. when tapping a tweet the timeline activity slides out and the tweet details activity slides in its place, with activities organized in a hierarchy. Android activities are roughly equivalent to view controllers on iOS, with a fundamental difference: installed apps can “vend” activities, that other apps can use as part of their activity hierarchy. For instance, a video player app can start with an activity listing the files found in its dedicated folder, then once such a file is tapped it starts the activity to play a single video, all the while also allowing any app, such as an email client or the file browser, that wants to play a video the ability to directly invoke the video-playing activity from within the host app.

I’ve always had reservations with this system: I thought it introduced user confusion as to which app the user “really” is in, which matters for app switching and app state management purposes, for instance. And I still do think so to an extent, but it is clear the approach has a lot of merit when it comes to the browser, given how pervasive visiting web links is even as part of otherwise very app-centric interactions. And maybe it could be worth generalizing and creating on iOS an activity-like system; sure, the web browser is pretty much the killer feature for such a system (I am more guarded about the merits when applying it to file viewing/editing, as in my video player example), but other reasonable applications could be considered.

So I’m asking you, would you like, as a user, to have activity-like features on iOS? Would you like, as a developer, to be able to provide some of your app’s view controllers to other apps, and/or to be able to invoke view controllers from other apps as part of your app?

Thoughts on developer presentation audiences

So after the WWDC 2015 keynote, reading Dr. Drang (via Six Colors) and generally agreeing with his take sparked some reflexions. In particular, as a software developer myself, a side reflexion about what (if anything) is particular about software developer audiences, so that people like Drake and Jimmy Iovine, in the unlikely case they read this, don’t think of software developers as a mean crowd; and who knows, it could be applicable to other show-biz types in case they present at events like Build or Google I/O.

But to being with, whose bright idea was it, honestly, to have Apple Music be the “one more thing” of a WWDC keynote? Especially of a keynote that was one of the longest, if not the longest, in recent history (I’d check, but is currently redirecting me to Only one of those (“one more thing” or “WWDC keynote”) would have been fine, but not both. You can have, at the end of a long presentation, at a time the attention of the crowd (which, if it needs to be reminded, was up very early and spent a lot of time in line, because otherwise you end up in an overflow room) may be waning, a “one more thing” about something outside of the theme, for instance new hardware announcement, on condition that this announcement relieves some pain points (e.g. new hardware that makes a previously impossible combination now possible, easing the life of developers who use one and develop for the other) or otherwise has elements that can spark the audience’s specific interest so that you can be guaranteed some cheers and applauses and keep the crowd interested. Apple Music, even if it materializes as a good product, does not have that.

Don’t get me wrong, software developers like music just as much as the next guy. And heck, we’ve seen worse, including at WWDC or iPhone SDK events (Farmville, anyone?). In fact, software developers are not a tough crowd; they will almost alway give at least polite applause when cued: I remember the Safari kickoff presentation at WWDC 2010, with an audience therefore presumably dominated by web developers, and Safari extensions ended up being introduced, with one of the presenters presenting… how they ported their ad blocking extension to Safari. To an audience at least in part making a living (directly or indirectly) from web advertising. Even then, he got polite applause at the end of his presentation, like everyone else. And outside of very specific, preexisting situations (it was at Macworld, but could just as well have happened at WWDC) software developers will never boo a presenter offstage. Why is that? Well, an important part is that software developers have been in the presenter’s shoes before; not to this scale, most likely, but they know it’s a tough part, either to have a demo that works (hence why the applause even for incremental features that were even seen on other platforms before), or worse, if there is no demo, to be able to convey the importance of the software you are talking about without being able to show it. And even if the presenter is mediocre, contrary to a mediocre artist, software developers know that applauding the presenter will not make him stay longer, and his script will end soon enough anyway, so might as well politely applaud.

Software developers, as tech enthusiasts, are more generally interested in anything that moves the state of the art forward, even if it has little relation with any technology they will actually make use of in their job, on condition they can see what is new or specific about it; or at least, they want to be able to take the announcement apart, as we’re going to see. Plus they are heavy users of the platforms they are developing for, so anything that makes user’s lives easier makes theirs easier, too, and they will react to that.

But software developers are also a wary bunch. All of them have been burned before; doesn’t matter whether they trusted a company they shouldn’t have or whether they couldn’t have foreseen anything but were betrayed, they all got a past experience of betting on something (a platform, an API, a service, a tool, etc.) and losing their bet. So in presentations they don’t want to be given dreams of an ideal future where the product magically does what we expect of it, but rather they want demos, or at the very least material claims that can be objectively evaluated as soon as anything concrete is provided. Triply so for Internet services. Everything else is just a setup to get to a demo, as far as a software developer is concerned. Also, as a result software developers take apart everything that is being said to try and figure how it works, in particular to foresee any eventual limitation; yes, to an extent it does take out the magic to dissect everything that way, but remember that for software developers this is a matter of survival. Again, triply so for Internet services. Do I need to remark that the Apple Music presentation, even the demo from Eddy Cue, provided little in the way of these material claims? He did show how the user interacts with the service, but, being an Internet service, this does not show how it works, really. Also, this means that the crowd may be too busy trying to make sense of what you are saying to react to your quick quips.

Software developers are also extremely good at math and mental arithmetic. It goes with the job. They will double-check everything you throw at them, live, so don’t ever expect to be able to assert claims that don’t literally add up.

As with any recurring event (as opposed to, say, a concert date, where this is less the case), there is also a lot of lore and unsaid things that are nevertheless known from both the regular presenters and the audience. If you’re not a regular presenter, it’s not something you can tap into (so yes, you will be at a disadvantage from the regular presenters), but you better be briefed about those to avoid running into them by accident. I remember a high school incident where I had an exchange with a classmate that the class couldn’t miss: it was about silex/stone blades, and I can’t remember what the root of the problem was, but I was countering that this was no way to build a hatchet that could chop down trees, to which my classmate countered that chopping down trees was not the guys’ aim. I think I let him have the point at the time; this was presumptuous of him to assume this, but at the same time it was presumptuous for me to assume this use case, this was just something I came up with as a use case for a hatchet at the top of my head. Fast forward a few months, but still in the same year, the class was making an outside trip to a place where they studied stone age tooling, and during his presentation the guy explained that following the methods from these times: preparing and carving the stone, pairing it with a wooden handle and attaching with then-current methods, he got a tool that worked very well, taking as an example that he had been able to chop down a small tree with it.

After maybe a beat, the whole class erupted in laughter.

My classmates had clearly not forgotten; the poor presenter was all “Was it something I said?” (I was tempted reach out to him, shake his hand and thank him profusely), and our teacher fortunately came to his rescue by promising to tell him later. There was of course no way he could have been briefed for this, but this is not the case for an event such as WWDC.

And, as a “one more thing”, I think I should close with a mention of the other WWDC keynote audience, those who watch the live stream, and react on Twitter instead. This is not exactly a developer audience, but pretty close. However, the reactions tend to be all over the place, in particular you always get the complaint (that ends up trending each time!) that no new hardware (or no new hardware the poster was interested in) was announced, even though this is a silly expectation to have: you can always hope for some, mind you, but given there is always a lot to say about future OS updates at WWDC, especially now with three major Apple platforms, it’s better for Apple to make these announcements at other times. So it’s hard to get a feel for the WWDC live stream audience.

WWDC 2015 Keynote not-quite-live tweeting

(Times are GMT+2)

  • 10:14 PM – 8 Jun 2015: Looking at the previewed Mac OS X improvement, I think it’s too bad @siracusa is not going to be reviewing them (but it’s his call) #WWDC15
  • 10:16 PM – 8 Jun 2015: Speaking of @siracusa , I’d almost prefer for multitasking dividers not to be repositionable. #positioning #OCD #WWDC15
  • 10:19 PM – 8 Jun 2015: Metal on the Mac: “Of course this means war” #OpenGL #WWDC15
  • 10:21 PM – 8 Jun 2015: At long last we have search in third-party apps on iOS! (viz. ) #WWDC15
  • 10:23 PM – 8 Jun 2015: (Around the 37 minute mark): It’s funny, because I’m actually exercising as I watch the keynote stream and take these notes. #WWDC15
  • 10:24 PM – 8 Jun 2015: Siri does still rely on network services, so it can’t all “stay on the device”… #WWDC15
  • 10:27 PM – 8 Jun 2015: (Around the 43 minute mark): the Apple guys have turned into Stanley Yankeeball (minus the Stanley) #WWDC15
  • 10:33 PM – 8 Jun 2015: These improvements to notes might be good, or might turn it into a mess(is it a word processor? For structured text? Something else?)#WWDC15
  • 10:35 PM – 8 Jun 2015: Mapping exits of tube stations is great, not even all of the transit systems’ dedicated apps do so. #WWDC15
  • 10:37 PM – 8 Jun 2015: Since it’s only in select countries at first, the new news app is more than just an aggregator and probably has some editorial. #WWDC15
  • 10:39 PM – 8 Jun 2015: Keyboard gestures for editing are great, but are they like cursor keys (more accurate) or more like mouse movement? #WWDC15
  • 10:40 PM – 8 Jun 2015: Yes! Yes! Yes! Yes! Split screen multitasking on iPad! Amply justifies upgrading to the Air 2. #WWDC15
  • 10:41 PM – 8 Jun 2015: I don’t know how practical multi-touch on multiple apps is, but it sure rocks. #WWDC15
  • 10:42 PM – 8 Jun 2015: New low power mode is the battery equivalent of low memory warnings. #WWDC15
  • 10:43 PM – 8 Jun 2015: Apple game development frameworks still aren’t credible as long as Apple is not dogfooding them. We want Apple-made games! #WWDC15
  • 10:45 PM – 8 Jun 2015: With Home Kit through iCloud, better hope that iCloud is secure… (or that this particular part can be disabled). #WWDC15
  • 10:46 PM – 8 Jun 2015: About Swift: open source is nice, standardization would be nicer. Yes, Objective-C isn’t a standard, but C and C++ are. #WWDC15
  • 10:47 PM – 8 Jun 2015: With iOS9 still supporting the iPad 2, get ready to have to support ARMv7 and the Cortex A9 for some time (it’s not hard, mind you). #WWDC15
  • 10:48 PM – 8 Jun 2015: Can’t really comment on watchOS improvements, since I don’t know much about what it currently does anyway. #WWDC15
  • 10:51 PM – 8 Jun 2015: With native Apple Watch apps, get ready for a “Benchmarking on your wrist” post from @chockenberry as soon as watchOS 2.0 lands. #WWDC15
  • 10:52 PM – 8 Jun 2015: (around the 1:40 mark): wasn’t expecting them to be ready to demo the new watchOS features live so soon after Apple Watch release. #WWDC15
  • 10:54 PM – 8 Jun 2015: (around the 1:41 mark): Kevin Lynch was tethered by the wrist during the Apple Watch demo. Is that punishment for Flash? #WWDC15
  • 10:56 PM – 8 Jun 2015: I was even less expecting them to have a new watch OS beta ready today, 6 weeks after the Apple Watch release. #WWDC15
  • 10:57 PM – 8 Jun 2015: Between Jimmy Iovine and the two women (sorry ladies, I did not write down your names), many new presenters, that’s great. #WWDC15
  • 10:58 PM – 8 Jun 2015: Interesting that they would present Apple Music at WWDC, would appear more fitting for an iPhone or music event. #WWDC15
  • 10:59 PM – 8 Jun 2015: I am more interested in music I can keep, though global radio is interesting. #WWDC15
  • 11:01 PM – 8 Jun 2015: Nothing has really replaced the records stores so far when it comes to music discovery. Will Apple Music do better than Ping? #WWDC15
  • 11:02 PM – 8 Jun 2015: With the news app and Apple Music, Apple is doing more editorial/curation than they ever did. #WWDC15
  • 11:03 PM – 8 Jun 2015: I won’t comment on Apple Pay until it reaches France. #WWDC15
  • 11:04 PM – 8 Jun 2015: Sure, you can ask Siri for the music used in Selma, but she’s no Shazam. #WWDC15
  • 11:05 PM – 8 Jun 2015: After the demo, my feeling of Apple Music is: Netflix for music. Android support is interesting… #WWDC15
  • 11:06 PM – 8 Jun 2015: Again, interesting to have a live performance at WWDC, rather than at an iPhone or music event. #WWDC15
  • 11:09 PM – 8 Jun 2015: And that’s it for the #WWDC15 keynote comments. Now back to notifying of new posts.
  • 8:53 AM – 9 Jun 2015: Some more post-sleep #WWDC15 thoughts before returning to normal:
  • 8:56 AM – 9 Jun 2015: First, there was no homage or reference (that I could spot) in the keynote to @Siracusa and his Mac OS X reviews, I’m disappointed. #WWDC15
  • 9:01 AM – 9 Jun 2015: Second, maybe it’s just me, but I get the impression the keynote is less and less for developer-level features. #WWDC15
  • 9:13 AM – 9 Jun 2015: Third, no free Apple Music tier means people won’t get the impression this is music they can access forever. #WWDC15
  • 9:15 AM – 9 Jun 2015: Fourth and I’ll be done: with Apple global radio, what happens to iTunes Radio? #WWDC15

Thank you, Mr. Siracusa

Today, I learned that John Siracusa had retired from his role of writing the review of each new Mac OS X release for Ars Technica. Well, review is not quite the right word: as I’ve previously written when I had the audacity to review one of his reviews, what are ostensibly articles reviewing Mac OS X are, to my mind, better thought of as book-length essays that aim to vulgarize the progress made in each release of Mac OS X. They will be missed.

It would be hard for me to overstate the influence that John Siracusa’s “reviews” have had on my understanding of Mac OS X and on my writing; you only have to see the various references to John or his reviews I made over the years on this blog (including this bit…). In fact, the very existence of this blog was inspired in part by John: when I wrote him with some additional information in reaction to his Mac OS X Snow Leopard review, he concluded his answer with:

You should actually massage your whole email into a blog post [of] your own.  I’d definitely tweet a link to it! 🙂

to which my reaction was:

Blog? Which blog? On the other hand, it’d be a good way to start one

Merely 4 months later, for this reason and others, this blog started (I finally managed to drop the information alluded to in 2012; still waiting for that tweet 😉 ).

And I’ll add that his podcasting output may dwarf his blogging in volume, but, besides the fact I don’t listen to podcasts much, I don’t think they really compare, mostly because podcasts lack the reference aspect of his Mac OS X masterpieces due to the inherent limitations of podcasts (not indexed, hard to link to a specific part, not possible to listen in every context, etc.). But, ultimately, it was his call; as someone, if I remember well, commented on the video of this (the actual video has since gone the way of the dodo): “Dear John, no pressure. Love, the Internet”. Let us not mourn, but rather celebrate, from the Mac OS X developer preview write-ups to the Mac OS X 10.10 Yosemite review, the magnum opus he brought to the world. Thank you, Mr. Siracusa.

April’s Fools 2015

As you probably guessed, the post I made Wednesday was an April’s fools… well, the kind of April’s fools I do here, of course: just because this was for fun does not mean this was no deeper message to that post (now translated to English for your understanding).

In case you missed it, for April the first (besides posting that post) I translated to French my greatest hits (as listed there) and a few other minor posts, replaced all others with a message in French claiming the post in question was being translated, replaced the comicroll with an equivalent one listing French online comics, and translated to French all post titles and all elements of the blog interface: “React”, search, dates, etc. up to the blog title: “Le Programmeur Itinérant” (it stayed that way a bit longer than the initially planned 1-2 days because of unforeseen technical issues, my apologies for the trouble). Thus reminding you, in case my name did not make it clear enough, that even though I publish in English my first language is actually French.

The problem of availability of information, especially technical one, in more than one human language has always interested me, for reasons of inclusiveness among others. It remains a very hard problem (I did get a good laugh at the results of Google translate back to English when applied to my French posts), and so initiatives such as this are very welcome (they translated my “A few things iOS developers…” for instance, but I can’t find the link at the moment).

Lastly, there have been a few influences that led me to do this for April the first, but I want to thank in particular Stéphane Bortzmeyer, who manages to maintain a very technical blog in French; whenever I needed the French translation of a technical term I could typically just look in his blog to see what he uses (or to confirm there was no point in trying, e.g. for “smartphone”, which has no real French translation). Much respect to him for this.