Tagged: From Old The Powers of Observation Blog

My Lists from 2010

If you have blogging software, you’ll often have a bunch of old draft posts, which just keep getting more and more outdated, greet you every time you open the app.

My version of this is two posts, “10 Things I Was Proud of as an Apple Engineer” and “10 Things I Wasn’t Proud of as an Apple Engineer”, started in 2010 after I left Apple.

I finished the first one, but the references in it are too old to post now. And I didn’t even get to 10 on the second; I was only able to think of 9. So I’m just going to publish the lists as-is, for a bit of nostalgia:

Proud:

99-cent songs
No-DRM music
WebKit
Environmentally-friendly progress on hardware
Infrastructure-improvements-only Snow Leopard
OS X-based mobile strategy
iOS itself
iOS’s delayed, done-right multitasking introduction
iPad
Clang

Not Proud:

“100 features” nonsense
Increasingly cheap WWDC amenities
Killing WWDC feedback sessions
Breaking own HI guidelines
Ongoing BugReporter crappiness
Suing bloggers
Suing competitors
App Store review arbitrariness
Corporate war with Google

A Mergin’ Behavior

Now that I’ve merged the storyboard file format (which is also basically the new xib format) in a real-world project, I can say the following:

It is…more than just easier, it’s now possible.

Which is a great relief.

The trick (the one weird tip, as it were) is that the file format stores pieces of data that should be single, undivided snippets of the file, as single undivided snippets of the file, in a human readable format.

For example, objects are represented by a single XML node, whose name is that object’s type. You can tell what a tableViewCell node is just by its name. And you know what it means when it contains a tableViewCellContentView node, and you know what it means when that node contains a subviews node. And so on.

This leads to several benefits:

  1. A single change to the file, say adding a background color in a view, only affects one spot in the file, unlike previous formats, where a single user-initiated change to the file might wind up modifying multiple places in the file itself. So unrelated changes to different objects won’t wind up being merge conflicts.
  2. When you’re reviewing the changes from a merge, it’s easy to see that they’re the ones you expect. To use the same example as above, if you’ve added a background color to a view, that will add a color node inside that view’s node.
  3. Because you can identify the changes you want, you can also identify the changes you may not want. For example, you can easily reset the changes Interface Builder makes to the xib/storyboard’s header to reflect the current version of Interface Builder and the operating system, if you don’t want to see such noise as part of your commits, without worrying that you’re accidentally modifying something you don’t understand.
  4. You can work around Interface Builder bugs. For example, currently in Xcode 5, if you refer to the same image in multiple places in a file, it will add several entries representing the image to the resources node at the bottom of the file. Then, it will complain to you in a sheet about “internal inconsistencies” (while leaving in the duplicate entries). You can merely refuse to commit the IB changes that introduce those duplicates, which will prevent the problem (though not the alerts).

The last point can be expanded to a broader theme: you should use formats and architectures in your application that don’t try to fight the way the world works. If your architecture requires a perfect app to work well, then your architecture isn’t very well suited to the current world of software development, where there will always be bugs.

As described above, the current storyboard/xib format does not require a perfect app, and in fact allows end users broad powers to work around app bugs and peculiarities. This is in contrast to the previous format, which was not particularly human-readable, and therefore required the end user to trust that the app was doing the right thing in all cases.

Laying It All Out

My first encounter with Auto Layout in a real-world project didn’t go as smoothly as I would have liked.

Why not? Because it was a special case. (An…Edge Case, as it were.)

I was trying to customize the title view in a navigationItem. I changed the view’s width after I’d set it to be the title view, making it shorter. But I couldn’t get the change to “stick.” It remained the old width no matter how many times I modified it. (On iOS 7, at least. On iOS 6, worked fine.)

Since the storyboard I was working on had Auto Layout turned on, I thought maybe this was because I hadn’t set the constraints correctly. So I tried adding a constraint in code.

Bad idea.

First of all, that constraint conflicted with the constraint generated from the view’s autoresizing mask. In order to solve that, I turned off my custom view’s translatesAutoresizingMaskIntoConstraints property.

That led to a crash due to an NSInternalInconsistencyException. Reason?

Auto Layout still required after executing -layoutSubviews. UINavigationBar’s implementation of -layoutSubviews needs to call super.

Huh? Why was I being asked to fix UINavigationBar’s implementation of layoutSubviews? I went up and down the view hierarchy, used every Auto Layout debug trick I could find, added every constraint I could think of. I still couldn’t avoid this error.

The end.

Not really, but almost. I had to conclude the following: even if the rest of your storyboard uses Auto Layout, do not use Auto Layout in your own custom title view. Just don’t. Use springs and struts and be happy about it!

Also, if you want a different title view size after you’ve add it to your navigation item, well, remove it from the navigation item, change the size, then add it again. Then, and only then, does it work.

See what I mean about it being a special case?

But because I was new to the Ways of Auto Layout, I spent hours checking and double-checking that I wasn’t missing anything, that there wasn’t some special rule I was overlooking.

Nope.

The Sound of My Voice

Want to download something that contains my dulcet tones other than an Edge Cases podcast episode? If so, you might want to act fast. (Or you may not: see Updates at bottom.)

As you probably know, for the moment, you can go and access Apple’s WWDC presentations for 2012, 2011, and 2010 directly from their website. You can also access them through iTunes, where you can download them (in high def or standard def) and have access to them forever, something I recommend if there’s a particular older session you find useful.

If you look closely on that iTunes page, however (again, for the moment), you’ll see that there’s also a link for WWDC 2009 sessions, both Mac and iPhone.

And if you look in those, you’ll find, under both sections, Session 418 “Customizing Xcode for Your Development Workflow”. Or you could follow these links directly: current Mac link, current iPhone link. Let me know if those don’t work. (Update: the Mac link may not work for everyone.)

That was the last session I helped to present at WWDC.

It’s interesting for me to go back and listen to how I sound and how I present myself. No “Um”s or “So”s here! No stupid jokes. (Well, fewer stupid jokes.) We practiced over and over and over again. Practiced the wording, practiced the pacing, practiced the demos.

For Edge Cases, we don’t practice at all, and there is at most a few hours of preparation. So: a lot less polished, but I can speak my mind. It’s worth the tradeoff, I think.

Note that knowing me or the other presenters is probably the only reason to download this. In the session, we’re talking about Xcode 3, since superseded by Xcode 4 and later WWDC sessions.

And I suspect that sometime after they get around to releasing the sessions for WWDC 2013, promised to be during the conference itself in a few weeks, the oldest sessions will go away for good.


P.S. Speaking of which, did anyone download the 2007 (found it!) and 2008 (found it!) 2006 WWDC sessions when they were available? I’d love to get a copy of my session from that year, too.


Update #1: Thanks to Neil in the comments, I see that there are in fact some older sessions available back to 2004.

Whether you think older session downloads are in danger depends on whether you think there were more/all sessions original available for those years, and they dropped some of them over time, or whether you think that these limited sessions were all that were ever available, and so no culling has ever occurred.

I kind of hope it’s the former, because while the newly-revealed sessions do include the 2008 session I was looking for, they don’t include the 2007 session I wanted. So: still looking for that.

Update #2: OK, so I’ve found the 2007 and 2008 sessions I wanted, which were there all the time. My fault! But it turns out I had forgotten I’d done a session in 2006, too. The 2006 sessions are really sparse, and I don’t think I’m making a mistake when I say I can’t find my session there. So, at the risk of repeating myself: still looking for that.

Adventure Addendum

I omitted a couple of things from my latest Edge Cases topic, text adventure games (“A Programmer and a Puzzler”), due to time constraints, forgetfulness, etc., so I wanted to talk about them here.

First, I wanted to mention the very first text adventure game I played as a kid, Mission Impossible by Scott Adams. It was on a big, bulky cartridge that I plugged into my home computer. I remember getting hopelessly stuck at one point, and thinking, well, that’s it. There was no Internet to consult. In hindsight, I could’ve dialed up some sort of electronic bulletin board for hints, but that wasn’t something I knew how to find back then.

I played it again after recording the podcast, since now it’s available for free online (see above link), and…got completely stuck again. I had to turn to a walk-through, which made it entirely unenjoyable for me to continue playing. Still not any good at puzzles, it seems.

Second, I mentioned in the podcast that the TADS syntax I used to write my games was very similar to C language syntax. Now, that’s true of the TADS language. But the vastly more popular IF programming language Inform (which I also mentioned) has a syntax based on natural language. That syntax looks quite different and can be quite a bit easier to write. Check out this link for a screencast that introduces that syntax and the Inform development application, which has a lot of neat features. If you’re going to start writing a new IF game, try Inform first.

Third, I made it sound in the podcast like there were no graphical adventure games before Myst, which is wrong. While Myst heralded an era of CD-based games with much more rich multimedia content, there were plenty of graphical games distributed on floppies beforehand. I even played one of them: Indiana Jones and the Fate of Atlantis, which I enjoyed because its puzzles were exceptionally easy.

And finally, I mentioned on the podcast that I liked how the free games published by authors using languages like Inform were much more likely to survive platform transitions, like the PowerPC to Intel transition of OS X, because they were data files, not full executables. This was in contrast to commercial games like the ones from Infocom, which had been reissued for the Mac, but many years ago, and were no longer runnable.

These days, however, if you search on Infocom on the iOS App Store on iTunes, you’ll find an entry Lost Treasures of Infocom, including many (but not all) of the games from the 80s, available to download for free. (Though you’ll have to pay $10 to actually unlock all the games.)

The way these games were updated for iOS deserves its own blog post, so I’ll be doing that at some point. As a preview, I’ll say: I wish they’d done it better.

A Plist Apart

Or, a Story in Eight Pictures

We’ve all used Xcode’s special plist editor, which has a structured editing environment so you don’t have to maintain the XML formatting yourself, and provides a bunch of standard Info.plist keys. Very useful.

Xcode's plist editor

But if you do want look at the XML for a plist file in your project, it’s easy right-click on the file in the navigation pane and, under Open As, choose “Source Code”.

Xcode's Open As submenu

Xcode's source code editor

But what if it’s a standalone file? There’s no navigator pane, so there’s nothing to right-click on to bring up the contextual menu.

Non-project plist file in Xcode

Luckily, you can press Cmd-zero, or use the View → Navigators → Show Navigator menu item. This opens the navigator pane, which, here, only shows the one file instead of the contents of an entire project.

Xcode's View / Navigators / Show Navigator menu item

Then, you can right-click on the file as before.

Open As again

Many standalone Info.plist files are saved as binary, however, and Xcode won’t automatically translate that to text for you. But if you open the File menu, and hold down the Option key, you’ll see the Save As menu item, which will let you save over the existing binary as Property List XML.

Xcode's Save As menu item

Xcode's Save As plist options

The trick here, at least in Xcode 4.6, is that it still won’t let you look at the file as Source Code unless you close and reopen it.

Portrait Schmortrait

Since you did so well with my last iOS rotation question, I’ve got another one for you.

In the code I’m working on, we show a login screen if you’ve timed out, by inserting the login view as a subview of the current view. We should be using presentViewController:animated:completion: or some sort of navigation controller push, but we’re not, and can’t switch to anything like that for this release.

The login screen, on the iPhone and iPod touch, should be in portrait. (Again, whether this is the best idea or not is a question for another time.)

The standard rotation APIs are good at keeping you from switching away from your current orientation — for example, preventing you from switching from portrait to landscape if you started out in portrait. But what they aren’t good at doing is, if you’re already in landscape, forcing the view to show itself in portrait. And you need this if you want to actually enforce a portrait-only view, so it seems like an important omission to me.

There is a hack that works in iOS 5, documented in this Stack Overflow question, to force a view to display in a particular orientation regardless of the physical orientation. But it doesn’t work in iOS 6.

So anybody know of a new hack that will work in iOS 6? Or, better yet, a less hacky fix that will work in all OSes? I’ve made a new GitHub project, Portrait Schmortrait, that demonstrates the problem (and the working iOS 5 hack). Thoughts? Contact me in the comments here or on Twitter.