Summer Xcode Tips

June 22nd, 2006

It’s summer! The sun is out and the sky is (leans right to peek outside), well, sort of greyish. While the world celebrates the changing seasons, we’re all leaning over our keyboards and squinting into the screen, working on our LCD tans. All this warm weather puts me in the mood for Xcode tips! I’ve been saving up a few “gotta share” revelations. Are these tips no-brainers? Maybe for some of you. But it took me a while to “get it” and I’m hoping some of you will also giggle with glee when you learn out about them.

Hint #1: Double-Click to Open in External Editor

As my projects become more complex, they inevitably become the gathering place for an assortment of file types that support the production of and testing of the final product. Most of these files are source files, and Xcode is good at editing them. But others, such as scripting definitions and carbon resource files, are best left to external editors. Unfortunately, there are a number of file types that Xcode thinks it’s a good editor for, when it really isn’t. Even some source files might be better edited by external applications, depending on the particular goal.

I’ve spent a lot of time right-clicking such files and selecting “Open in Finder” from the contextual menu. This has the desired effect of opening the file in whatever application you’ve specified as the file’s owner via the Finder. That’s not a bad solution, but it’s slightly annoying, and not nearly as streamlined as double-clicking. But when I double-click a typical file that Xcode claims understanding of, it opens in a separate Xcode editor window. Ugh! I wanted to open in the external application!

From the “File Info” window in Xcode, you can tell Xcode what type you want it to consider the file to be. This is handy for things like making it apply Objective-C++ rules to a “.m” file, but the list of file types it’s prepared to acknowledge is really vast. As I set out to convince Xcode to open my file with another app, I thought I surely needed to teach it more specifically what kind of file it is. It’s not a text file, it’s an XML text file. No dice. Xcode “handles” that, too.

The answer to this problem is surprisingly simple, but it requires counter-intuitive (to me) reasoning. Instead of being more specific about the file’s type, you have to be less specific. Among the myriad choices is an item called simply “file.” When a file’s type is “file,” what do you know, it opens up with the Finder when you double-click it.

Note, if Xcode has already “laid claim” to being editor of your file, it probably has an open file reference to it somewhere. It will not give up its role as editor until you close the file. You can do this by choose “Close File [Blah]” from the File menu while the file is focused, or by pressing the shortcut Cmd-Shift-W.

Hint #2: Eliminate Build Configuration Strain

Since Apple announced the transition to Intel, quite frankly the hardest development aspect for me has been keeping all the darned build settings straight. If you are willing to target 10.4 and later, things are pretty straight-forward. But if you live in the real world and need to continue supporting older release of Mac OS X, things get trickier. To support earlier than 10.3.9 and Intel in a single universal binary, you have to use separate compilers at a minimum, and probably separate SDKs as well.

If you’ve had to do this for one or more of your projects, you probably got used to locating, copying and pasting the build settings from one project to another. Yuck! Not only is this prone to error, but it is “stupid work” that takes up a lot of time and energy. Apple’s answer to this problem is the “.xcconfig” file, which allows you to specify a number of baselines build settings outside the scope of a build configuration.

These “.xcconfig” files are simple text files containing variable names and their desired values. For instance, here are the contents of a baseline file I use for “Universal builds that need to run on 10.2”:

ARCHS = ppc i386
SDKROOT_i386 = /Developer/SDKs/MacOSX10.4u.sdk
SDKROOT_ppc = /Developer/SDKs/MacOSX10.3.9.sdk
GCC_VERSION_i386 = 4.0
GCC_VERSION_ppc = 3.3
MACOSX_DEPLOYMENT_TARGET = 10.2

I call this file “Universal 10.2+” and keep it in a common location accessible to all of my projects. Now when a particular build configuration in any project needs to “inherit” these settings, I use the “based on” feature of Xcode’s build configuration system. You simply drag a reference to the “.xcconfig” file to your project, whereupon it becomes available in the appropriate popup menu:

Notice that in this case I’ve chosen to name the “inheriting” build configuration “Release 10.2+”. There is a method to this madness: by adopting a naming convention for build configurations that match the system requirements, I can easily ensure that libraries from dependent projects get built under the same settings. By using a consistent naming scheme, and pointing all such build configurations at the same “based on” configuration file, I can rest assured that changing the settings in one place will percolate out to all the affected targets.

Also notice that “Architectures” is not even set by the project (it would be bold if it were). The setting of “ppc intel” comes from the configuration file. The project yields responsibility for defining what “Universal” means. So if Apple adds the rumored support for the Z-80 processor, I’ll only have to change the settings in my “.xcconfig” file.

I’ve barely scratched the surfaces of these files’ power. On top of the “based on” notion from Xcode, the files themselves can also explicitly include other files to stack a great deal of common build-setting definition into your process before the project-specified configurations are even reached.

Hint #3: Install a Directory of Changing Supporting Files

Let’s say you’ve written an application with an awesome templating system. You allow your customers to write their own templates and use them as the basis for new documents. To get your users off to a good start, you include a bunch of built-in templates in your app. In fact, your system is so good that there are literally hundreds of built-in templates and you’re adding more in every release.

All you want Xcode to do is put your directory full of “Built-In Templates” into the resulting application’s “Resources” directory. If you’re like me the first thing you think of doing is simply adding the directory of templates to Xcode, and then dragging the resulting folder icon to the “Install Bundle Resource” build phase. After all, that’s what this standard build phase is for, right? Yes. But the standard build phase does something annoying. Instead of copying the directory to the resources folder, it copies each individual file over to the root of the resources directory. This makes for a very cluttered resources directory.

The good news is that a simple “Copy Files” build phase of our own can get the job the proper way. Just add a custom build phase to your target with target directory “Resources”, and copy your folder reference to that. For some reason the built-in resources phase is “smarter” than it perhaps should be.

Note: When you add your directory filled with templates to the Xcode project, make sure to check the box that requests “folder references” be created. This is how you tell Xcode to take the folder as it is at any moment. Instead of adding the contents of the folder to the project as a group, it will dynamically refer to the contents of the folder as they are at any time. Now when you add new templates to the folder, they’re automatically copied into the app’s resource folder when you next build.

13 Responses to “Summer Xcode Tips”

  1. Nate Says:

    For “Hint #1: Double-Click to Open in External Editor” you can also go to Xcode/Preferences/File Types to change the default editor at a global level, rather that at a per file level. (if that suits your needs.)

    This data seems to be stored at ~/Library/Preferences/com.apple.Xcode.plist under PBXFileTypesToDocumentTypes, and PBXExternalEditorList, and appears to be loaded when Xcode launches. Upon examination, I found the structure for PBXExternalEditorList string format to be a fairly interesting and creative solution to storing multiple keys in a dict.

    Happy Thursday.

  2. Stilgherrian Says:

    “It”™s summer! … While the world celebrates…”, you say. Uhuh. Actually, only half the world is starting summer — less than half, even, because the tropics stay pretty much the same all year round. Not all of your readers are in the northern hemisphere temperate zone…

  3. Daniel Jalkut Says:

    Stilgherrian: I will confess to a little hemisphere-centricism. It is my blog, after all. And I live in a place that just got very warm. Am I not allowed to react to the changing of my local season?

    If you’re going to get picky, I didn’t say the world was celebrating the start of summer. I said it was celebrating the changing of the seasons. But perhaps I did offend the subset of the world that, like you, seems opposed to celebrating much of anything.

  4. leeg Says:

    In reply to Nate, that’s definitely the “proper” way to be getting Xcode to use external editors. I use it on my WebObjects projects, because the built-in data modeler is buggy and sucky so I set the opener for eomodels to be EOModeler.app.

  5. Daniel Jalkut Says:

    About the external editor thing. Thanks, guys. As I was grappling with this and then writing I was wondering about the wholesale external editor support. I know some people use BBEdit or TextMate, for instance. I’m glad to know there’s a way to set the editor for a file type en masse, I should definitely do that at a minimum for types like Sdef files.

  6. Non Stop Mac Says:

    Summer Xcode tips…

    Daniel Jalkut writes: “It”™s summer! The sun is out and the sky is (leans right to peek outside), well, sort of greyish. While the world celebrates the changing seasons, we”™re all leaning over our keyboards and squinting into the screen,……

  7. Stilgherrian Says:

    Daniel, I did see your “out” in that precise wording, and you’re right. But I can’t see how what I wrote indicates that I’m “opposed to celebrating much of anything”. Are you simply biting back because you feel bitten? Are we even? My extended reply now makes me look like I feel bitten, the one who’s molehill-mountaining. C’est la vie. I wanted to clarify my thoughts for my own writing anyway…

    What I find valuable about your writing is your introspection about the creative process, evident in posts like Blog Redesign and Another UI Bites the Dust. That material gives real insight, and you write well. Sure, the coding tricks are important too — especially if you’re a coder looking to solve that nagging problem that’s keeping you from meeting your deadline. But the more reflective material has a wider readership.

    So my comment wasn’t “having a go”. It was about maintaining your connection with that wider audience. And you just happened to trigger my response so your blog gets the content.

    People consume media not just because they find the content valuable. It also needs to fit their lifestyle — breakfast radio tells them traffic conditions at the precise time they leave for work. And there needs to be an emotional connection — “Hey, I like the guy who does this show, he’s like me,” even though they’ve never met.

    The converse is true too. A TV program that’s excellent in every other way loses audience because a new co-presenter has an annoying laugh. A writer loses audience through the build-up of trivial comments which trigger emotional disconnect — all subconsciously.

    So it’s good to write about how summer is affecting you, yes — especially if it triggers the reader’s own memories of summer, whenever that is, and whatever it means for them — because it starts to create that positive emotional connection. But in this case I hit a disconnect when I felt you made the assumption that all your readers were sharing this experience now.

    Oddly enough, I think the way around this is to be even more personal. Say, painting a word-picture of what summer is like in your home town, or from when you were a kid, or how the heat affects your workflow.

    This has precisely nothing to do with your coding tips, but I think that’s the point. I don’t read your blog for that, because there’s already far too many blogs by coders talking to other coders about coding.

    Now your reaction to this might well be “Who cares? I’m blogging for fellow coders.” And that is your choice, of course. But I think you have a lot more to offer than that. Hey, I’m being greedy! I just want to see more of what I enjoyed!

  8. Daniel Jalkut Says:

    Stilgherrian: Thanks for the thoughtful follow-up. I think I was cranky last night when I replied and just read more flame-bait into your comment than may have been appropriate. That’s the only defense I have for declaring you anti-celebration. Basically you’re right, you caught me being oblivious to the global nature of the audience.

    I feel the problem of a divided readership, and it’s frustrating to me, but I don’t know how to solve it. The blog started very explicitly as a Mac developer (coding) blog, but I know there are non-coders who now read on a regular basis. I suppose one way to solve it is to pick some very high-level categories and stick to using them on all posts to differentiate “coder” entries from “normal people” entries :)

    I’m glad you appreciate the parts of the blog that speak to you, and I hope you’ll continue skimming past the coding tips as they pop up.

  9. Stilgherrian Says:

    I’m guessing categorisation is the way to go — but don’t separate out the streams too much. Part of the joy of blogs, for me anyway, is the seredipitous discovery.

  10. Cameron Says:

    Thanks for hint #2 … think that is going to be a life-saver at the office this year.

  11. My Green Jar » Blog Archive » Xcode Tips Says:

    […] Many thanks to Daniel Jalkut for sharing some Xcode hints on his blog (link) . The best thing about mac development is definitely the development community. […]

  12. Adam Chester Says:

    Thanks as always for the hints. Number 2 is worth its weight in gold!

  13. Friday morning Apple links | Ars Technica Says:

    […] Red Sweater Blog has a list of Summer Xcode Tips: "All this warm weather puts me in the mood for Xcode tips! I’ve been saving up a few […]

Comments are Closed.

Follow the Conversation

Stay up-to-date by subscribing to the Comments RSS Feed for this entry.