It’s not like I don’t have better things to do, but on the verge of sending a build to testers, and knowing I would probably forget to update the version number sooner or later, I set about putting a build date into my Xcode project. And for fun, I did it one better.
First off, the build date is pretty easy. Open up your project’s targets and right-click to do an “Add → New Build Phase → New Run Script Build Phase”. Under the Target, you’ll see a gray box called “Run Script”. Drag this to the top of the list of build phases – we want to do this step first – and do a Cmd-I to bring up its inspector. By default, scripts run with /bin/sh, which is fine. For the script body, just enter:
date > builddate.txt
Do a build and inspect your project’s directory to verify that the builddate.txt file got created. It’ll look like this:
Tue Nov 24 10:29:31 EST 2009
Assuming the file got created, drag the file to the “Resources” folder in your project. This will add a new item to the “Copy Bundle Resources” build phase, which is exactly what you want: the script will create the file, and then the copy phase will copy the file to your bundle. You probably don’t want to source control builddate.txt, since it’ll be created as part of the build (of course, if you don’t, anyone who checks out your project will see those files in red, since they’re missing, until they kick off a build).
Now it’s easy in code to get the contents of this file into your GUI or wherever else you need it (in my case, this code is in the “about” view controller’s viewDidLoad:):
buildDateLabel.text = [NSString stringWithFormat:@ "Built on %@",
[NSString stringWithContentsOfFile:
[[NSBundle mainBundle] pathForResource:@"builddate" ofType:@"txt"]
encoding: NSUTF8StringEncoding error:nil]];
Oh, but that’s not enough. I decided it was necessary to also let my testers know what tunes they should be listening to. So I added the following AppleScript file (inspired by Erik Rasmussen’s) to the project:
set track_name to ""
set track_artist to ""
tell application "iTunes"
try
if not (exists current track) then return "(nothing playing)"
set track_name to (get name of current track)
set track_artist to (get artist of current track)
end try
end tell
set build_tune to track_artist & " - " & track_name
The script’s return value is a string with the artist name and the song name, with a separator. If you call the script from the shell, it’s trivial to then dump the returned string into a file. So, create another Run Script Build Phase (you might want to rename these phases from the generic “Run Script”, BTW). This time, the script is:
/usr/bin/osascript iTunesTrackReader.scpt > itunestrack.txt
Again, drag this build phase before the Copy Bundle Resources phase. Once you’ve done a build, the itunestrack.txt file will exist, and you should copy it to the Resources folder, so it will get copied into your app bundle.
In the code, the “artist – song” string got a little wide on the phone, so I used a two-line label and replaced the separator with a new-line:
NSString *twoLineString = [[NSString stringWithContentsOfFile:
[[NSBundle mainBundle] pathForResource:@"itunestrack" ofType:@"txt"]
encoding: NSUTF8StringEncoding error:nil]
stringByReplacingOccurrencesOfString: @" - " withString: @" -\n"];
iTunesLabel.text = twoLineString;
And here’s the result (click for full-size):
OK, probably could have made better use of two hours, but it’s checked in now. Plus, it’s like an automated version-naming system: “are you running the “American Idiot” build or the “Kind of Blue” build?”
Like everyone else, I’ve tired of Obj-C’s dance of redundancy, specifically having to declare interface variables for properties if you want to run in the simulator (or the “old” Obj-C runtime on Mac). To speed things up, I create the ivars first, then copy-and-paste outside the @interface block to set up the properties. Which still sucks, because I have to prepend every line with the @property declaration.
9 times out of 10, the property is for a UI outlet, so I’m always setting it up as @property (nonatomic, retain) IBOutlet IvarType *ivarName
To speed things up, I finally figured out how to set up an Xcode text macro for this:
{
Identifier = objc.property-iboutlet;
BasedOn = objc;
IsMenuItem = YES;
Name = "IBOutlet @property";
TextString = "@property (nonatomic, retain) IBOutlet ";
CompletionPrefix = "@property";
OnlyAtBOL = YES;
IncludeContexts = ( "xcode.lang.objc.block" );
},
Then I used the Keyboard system pref to add an Xcode-only keyboard shortcut to the “IBOutlet @property” menu item (right now it’s cmd-option-I… we’ll see if that sticks).
And all this makes setting up my properties suck just a little bit less.
I’ve tried Xcode 3.2′s Build-and-Analyze tool several times and felt that it was picking up nowhere near as many bugs as running Clang Static Analyzer directly from the command-line does. Suspecting that the integration of CSA into Xcode is a work in progress, I downloaded and installed the latest command-line version (v. 0.219) and tried it out:
** BUILD SUCCEEDED **
scan-build: 23 bugs found.
scan-build: Run 'scan-view /var/folders/ba/baOL2wJxE8aPV3tF1AeZsU+++TI/
-Tmp-/scan-build-2009-09-16-1' to examine bug reports.
Of these 23 (none of which were flagged by Xcode 3.2′s Build-and-Analyze), 9 were honest-to-goodness memory leaks (alloc without release or autorelease), and the other 14 were complaints about my use of old-fashioned rand(), which CSA thumbs its nose at:
warning: Function 'rand' is obsolete because it implements
a poor random number generator. Use 'arc4random' instead
Anyways, word to the wise: get comfortable with the command-line version of CSA, and keep watching the project’s website. One of the developers there told me they’d eventually be providing info on how to integrate new builds of CSA into Xcode.
BTW, we had instructions on how to set up command-line CSA in most of the betas of the Prags’ iPhone SDK Development book, then pulled it when we saw the analyzer was going into Xcode 3.2. What we’ve done instead is to split that material into a PDF that will be in the downloadable sample code zip (doesn’t look like it’s there yet, though).
Speaking of the book, I’m told it is now at the printer, so those of you who’ve pre-ordered it should expect your copies soon.
Anyways, now to see if the guys at CocoaHeads Ann Arbor were right about being able to build iPhone projects with Clang/LLVM. I thought that only worked for Mac projects right now.
I was experimenting with UITableViewCells late last week and wanted to show off a couple things I thought were interesting, and decided to do so in the form of a screencast.
The demo is an experiment I did to get UITableViewCells to “flip over”, by doing a transition with Core Animation. I ended up doing a few nib-loading tricks that are worth remembering, and wanted to share. So here’s the FlippyTableCellThrowaway Xcode project as a .zip file, MIT licensed (seriously, do what you want with it, don’t even bother with attribution, just don’t be a dick by passing it off as your own work).
This was also an experiment for me in terms of shooting and narrating a completely off-the-cuff, no-edits screencast. I haven’t even bought proper screencast software, so you can see the iShow U watermark throughout (and I only chose iShow U because Screenflow‘s watermark is far more prominent).
Anyways, hope it doesn’t suck. This was a total hack job in terms of code (haven’t even removed all the log messages and commented-out mistakes) and screencasting, so buyer beware.
I’m packing for the move in a week, dealing with boxes of papers in the storage room that haven’t been opened since the last move, a pretty good hint they need to at least be considered for the dump.
Above is a betacam tape of one of my Headline News shows from 1997, looks like a day when I was producing a full live hour, with this half directed by Bruce Daniel (who still works there, and whose wife is a good friend of Kelly’s). I think I kept a couple of these tapes just in case I needed them for pursuing another producing job, though the rigid format of Headlines back in that day meant that one producer’s show really ought to look pretty much like anyone else’s, so there really wouldn’t have been much value showing anyone this tape, short of pointing to the back of my head in the control room on the show-opening Camera One zoom and saying “see, that’s me!”
One thing about the format is that different producers still had flexibility within the format to pick their packages (with the guidance of a supervising producer) and fill out their 13-minute news block however they saw fit. We had one associate producer (which is what I was) who, when he did live hours, tried to give the audience something different by using cold opens, or effecting through some VOs with a “in this half hour”, or stuff like that.
I rarely did that, but what I often tried to do was to get more new stories into the system by digging through the wires (especially state wires, features, business, and Reuters’ “odd” wire) and, if I didn’t have enough writers to take on extra work beyond the necessary updates, I’d just write it myself. There was a full-blown producer named Alicia who also did this. We thought it was good for the Headlines ecosystem as a whole, because the new stories could be duped into later shows, so there’d be more variety in the next 23.5 hours. But in retrospect, the downside of this approach is that were writing from the wires instead of writing to available video, and usually ended up only having a box right for our new read. So on the one hand, we had new content in a textual sense, but were we really creating new “television”? My older self argues against my younger self on this one: today, I think I would have used the time to look through the feeds and see if I could find some good unused video, even if the story wasn’t as good.
So, also in the boxes of vanity, I found this little embarrassment:

Yep, I tried to write a Star Trek: Deep Space Nine spec script. Not that I was alone. Trek was the only show that regularly accepted spec scripts from unagented writers. To wit:
As they point out, 99.9% of spec scripts are sent packing with a “thank you very much”, though a few writers were able to break through this way, and it’s to Paramount’s credit that they were so open to new writers, and to their fan base, in this way.
I didn’t submit this script, in fact, because I knew then that it was bad (and can’t bring myself to read it today). I had about two acts plotted out and started writing, which ended up pretty much how you’d expect: somewhere in the middle of Act IV, I was just throwing words on paper, not knowing what the fuck I was doing or where I was going. In fact, the only reason I don’t trash all remaining copies of this (for fear of my children finding it in my effects 30 or 40 years from now), is the fact that I also found some notes where I was radically re-breaking the story for a thoroughly overhauled second draft:
A rewrite might not have made it good, but it would certainly have made it better.
Before drifting into CNN, I think I ended up writing maybe four total spec scripts. Clearly not enough, and it was not something I did often enough for the process to get easier. Maybe you have to write 10 scripts before you write a good one, but if you don’t truly think the first 9 can be any good, how the heck do you turn them out?
I’ve felt this in an accelerated way with iPhone work since getting the SDK earlier this year. My first couple were tentative, confused, and sometimes appealed for Java analogies that weren’t there. Two things that helped were trying to do some ambitious work early on (my still-broken web radio client) rather than just “screwing around” with the SDK, but then getting into a groove of creating a number of projects and getting familiar with the process of creating an XCode project and being increasingly purposeful with where I wanted to take the code.
Writing an application and writing a screenplay have certain strange similarities. Aside from having to start with an empty “new document” window and needing to bring life to the void, there’s also a sensation that when things are set up right, they just run themselves. In code, those are methods, delegates, and program states. In writing, it’s character and situation (indeed, plot is sometimes defined as character plus situation… define both of them well enough and your story writes itself).
As for my spec scripts, they fell by the wayside while I worked at Headlines. I tried to write a Home Improvement spec to keep the Hollywood screenwriter dream alive, but aside from having some gags and a general premise, I could never get the feel for the straight sitcom. My two half-way decent specs are animation (a spec for Animaniacs which got a nice read from WB and a copy of a real script from the show, sort of a gentle “do it more like this”), and an off-the-wall sitcom pilot we did in grad school called Public Access, which was a finalist in a couple of competitions, but not a winner. It still has some of my favorite gags, the recurring show-within-a-shows like “Can You Fit A Hamster Through A Funnel?” and “Show Dyslexia The”.
Had I taken my chances in LA rather than playing it safe at CNN, I might have taken the next step beyond these scripts, but then again, I might also have crashed and burned and wasted even more time. Guess we’ll never know… short of finding a way to an alternate universe where things played out that way. Which, I think, is what my DS9 was about.
I’ve been doing a lot more iPhone coding this week, finally putting together app logic (where I started with my iPhone work) with GUI. It’s starting to come together faster, and I find I’m remembering more details and making better first guesses, often in lieu of digging through docs.
I wouldn’t have said this last night, hung up on a problem with the navigation stuff. What I found is that a sample app I was working from is highly dependent on side effects and relationships expressed not in code but instead implicit in Interface Builder. Just work from the guides and be willing to build dynamic parts with code and it’s not bad at all.









