Development tools



Relevant resources


Documentation


Video - Apple


Web


Podcasts


Books



Version control


Every modern developer should be using some sort of source code management system for all but the smallest projects.  Version control acts as a safety net and allows you to perform stress-free experiments with your code.


Subversion comes pre-installed on Leopard and Snow Leopard Macs, so it is a logical first choice for a version control system.  It also integrates nicely with Xcode, so it is what I use for my personal projects.


To create a repository, open up the Terminal, go to the directory where you'd like it to reside and type to following command:


svnadmin create [repository name]


replacing [repository name] with your actual repository's name.  Once the repository has been created, you can create your project, then add its entire directory into the repository using 


svn import [project directory] file:///[path to repository] -m "Initial import"


You may wish to organize your project directory around the standard /branches /tags /trunk directory structure before importing it into the repository.


Once the repository has been set up, you'll want to create a working directory by checking out a copy using a command like the following:


svn co file:///[path to repository] [working copy directory]


You then do all of your development within that working copy directory, and you can throw away the original project directory.


You can continue to add files, commit versions to the repository, etc. at the command line, or you can use a GUI client.  There are two great graphical Subversion clients for the Mac: Cornerstone and Versions.  I highly recommend trying them out, because they both make managing repositories easy.


Xcode can integrate with your Subversion repository.  To add your repository to Xcode, go to Xcode | Preferences... and navigate to the SCM tab.  On the left side, click the + button and enter a name for this new repository.  In the details for this new repository, set the URL to be the file:/// one you used above when creating the repository.


You will then need to associate this repository with your project.  Go to the list of files, select the project, and click on the Inspect button.  In the General tab, click on the Configure Roots & SCM button and add your repository to the project.  After you do this, you will be able to see lists of versions for each file, commit to the repository directly from Xcode, and add files to the repository.


A great feature of Xcode is the ability to see the modification status of each file in your project.  To enable this, go to the list of files and right-click on the header at the top of the window.  Select SCM and a new column will appear that shows the status of each file in the working copy (? for not in the repository, M for modified, A for added).


You can do graphical diffs within Xcode for any modified file in your version control system.


Recently, distributed version control systems have emerged as potential successors to Subversion.  The two most popular of these are Git and Mercurial.  Currently, neither of these systems are integrated with Xcode.


Xcode


Text editing


Autocompletion of method and class names is the primary reason to stick with Xcode for the text editing of your source code files.  By default, Xcode will show suggestions as you type, picking what it feels is the best match for the class or method you're typing.  If you hit Enter, Xcode will fill in the details for you, along with selectable parameter placeholders.  I find this distracting, so I typically disable it and use the Escape key to pop up a menu of possible completions.


Autocompletion options are contained within the Code Sense section of the Xcode preferences dialog.


Xcode 3.2 now auto-inserts starting brackets to match ending ones, a nice convenience.


There are a number of bound keystrokes for editing.  These include many ones familiar to Emacs users.  For text navigation, you can use and  to move the cursor between words, and ^ and  ^to move between parts of CamelCase words (particularly useful in Cocoa).  


You can toggle code folding by clicking on the arrows in the gutter of the editor or by typing ⌘^and ⌘^(toggles global folding).


For project organization, Xcode supports a couple of #pragma directives.  If you add something like


#pragma mark -

#pragma mark Initialization


a divider will appear in the pulldown list of methods at the top of the screen, with a boldfaced section header titled Initialization.


Xcode has some text macros included to aid input under the Edit | Insert Text Macro menu.  You can assign key bindings to these.  Key bindings for all menu items can be set in the  Key Bindings section of the Preferences dialog.


You can quickly flip between the .m and .h files for a class by hitting ⌘⌥↑.


You can navigate to your previous location within a file by hitting the back arrow at the top of the editor screen.


You can look up the definition of any symbol by right-clicking on it and selecting the Jump to Definition option or by Command-double-clicking on it.  To bring up quick help on the symbol, Option-double-click or select the appropriate option from the right-click menu.  To look up a symbol in the documentation, Command-Option-double-click on it, or choose the Find Text in Documentation option in the right click menu.


For those looking for a more powerful non-Xcode text editor, it's hard to beat TextMate.  It has a crazy number of macros and impressive scripting support.


Refactoring and snapshots


Xcode lets you perform project-wide refactoring.  This includes the ability to rename classes and methods (including all references to these), extract code into its own method, create superclasses, improve encapsulation, and move methods between classes and superclasses.


To refactor something, select it and choose Edit | Refactor.  You will be presented with a dialog that will preview the changes to be made.  In this dialog, you will be given the option to save a snapshot of your project before completing the refactoring operation.  


These snapshots let you roll back your project to a specific moment in time, and provide an easy means of undoing a complex editing operation like refactoring.


Build settings


You can control many aspects of how your application is compiled and packaged by manipulating its build settings.  There are two places where you can change these settings, which often leads to confusion.  You can set project-wide build settings by selecting your project in the Groups and Files window, bringing up the inspector, and going to the Build tab.  Settings for a particular target can be accessed by going to the Targets section of the files window, selecting a specific target, bringing up an inspector for it, and going to the Build tab.


Changes you make to the build settings are overridden in order of specificity.  Customized target build settings override project build settings, and settings customized in a build configuration override general build settings.


You can have multiple targets, which makes it easy to build multiple versions of your application from one project and one codebase.  I've done this to create separate free (Lite) and paid versions of my application.  You can do this by setting a different Product Name and by setting a custom value to the Preprocessor Macros (such as FULLVERSION).  The preprocessor macro value can then be used to trigger conditional defines in your code such as:


#ifdef FULLVERSION

// Do something specific to the paid version

#else

// Do something specific to the free version

#endif


A long list of warnings you can turn on in the build settings is given in "Warnings I turn on, and why" by Peter Hosey.


Always turn on Treat Warnings as Errors.  The dynamic nature of Objective-C means that many warnings the compiler throws at you (for things like undefined selectors) are showstopper bugs and would cause your application to crash.  


Another related warning I turn on for my projects throws a warning if you use a selector that doesn't match any defined method.  To enable this, set -Wundeclared-selector for Other Warning Flags.


Build phases


You can create custom build phases to perform operations like copying files into your project, or running some sort of script every time you build.  To add a new build phase, navigate to a particular target in your application's project, right-click on it, choose Add | New Build Phase from the pop-up menu, and select the type of build phase you'd like to add.


If you'd like to copy files into your application's bundle and place them in a location other than its main resources directory, you can create a Copy Files build phase and inspect that phase to add a new target location or subdirectory.  I've used this in the past to copy over my application's HTML help files, while preserving their directory structure.


You can run a script every time your application builds, which is useful for automating certain tasks.  I use such a script to tag my builds with their revision number.  To do so, I created a Run Script build phase, and inspected it to set the shell to /bin/sh and the script to the following:


REV=`/usr/bin/svnversion -nc ${PROJECT_DIR} | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'`

echo "#define kRevisionNumber @\"$REV\"" > ${PROJECT_DIR}/revision.h


this script writes out the current Subversion revision number of my working directory to the revision.h file, which I can then import into my application so that I can use kRevisionNumber to display the Subversion build number somewhere.  This has been particularly useful in beta testing, so that my testers could know if they were using the latest build.


Interface Builder


You should be pretty familiar with Interface Builder at this point, so I won't spend much time with it here.


Instruments

Shark


We will cover Shark and Instruments in detail when we cover performance tuning.