open -a /Developer/Applications/Utilities/Help\ Indexer.app ${BUILD_DIR}/${PRODUCT_NAME}.app/Contents/Resources/${PRODUCT_NAME}\ HelpNote that
open launches the indexer asynchronously, which means the build continues (and could finish) while the indexer is running. So, you may have to build the app a second time to make sure you don't get the old index.
Using PHP for your Help Books
One problem with help books is that they are restricted to being plain HTML files plus AppleScripts. There's really no nice way to "#include" a title or navigation area or a common design. PHP would let you do things like that. But PHP files need to be displayed through
Apache, with PHP turned on in the httpd.conf. This would require you to install your help book in the user's
Sites folder, mess with Apache's configuration, restart Apache and view your help through Safari (which doesn't have Help Viewer's great search feature, nor its facilities for integrating with your program).
But luckily, Apple started shipping along the new PHP command-line tool with MacOS X 10.3. So, if you can live with static content, you can generate HTML files from your PHP scripts through a simple command:
php script.php > page.htmOf course, we want to automate this. We can use the
find command to run this on all php files in a particular folder. But sadly, we can't have a redirect operator (">") in the -exec parameter to find. So, create a new shell script file "php2html.sh" and write the following script into it and
chmod +x it:
#! /bin/bash
php "$1" > "$1.html"
This script will take a PHP file path as its parameter and create an html file with the executed script's output next to it. Once that's done, all you need is a shell script build phase:
dir="./${PRODUCT_NAME} Help/"
find -d "$dir" -name '*.php' -exec "${dir}php2html.sh" '{}' \; -print
And after that, maybe another call to
find like above that deletes all the PHP source files after copying, or that copies everything
but PHP files from the project directory. Neat, huh? Just remember to run your help indexing script
after this one so there is something to be indexed.
Including the Subversion Revision in your App
I like to have the current SVN revision number somewhere in my app so there's a way to distinguish copies of the app even if I forget to bump up the version number. To do that, I use the following script:
#! /bin/bash
echo -n "Finding revision in "
pwd
revnum=`/usr/local/bin/svnversion . | cut -f '2' -d ':'`
# Now write the constant declaration to the file:
echo "#define SVN_VERSION \"$revnum\"" > svn_version.h
echo "Wrote revision $revnum to svn_version.h"
This creates a file named "svn_version.h" in the project's folder that contains the statement
#define SVN_VERSION "46". I.e. you get a string constant that you can use in your C files wherever you want to display the current revision. It's important that this is a string, as a modified working copy gets a version number like "46M", which would cause trouble if you use an int.
Build and Upload File for Deployment
I also have a neat little shell script that switches my project's build style to "Deployment", builds it, compresses it and uploads it to a web server:
#! /bin/bashecho '===== BUILDING FILIE FOR DEPLOYMENT ====='
cd `dirname $0`
xcodebuild -project Filie.xcode -buildstyle Deployment clean build
cd build/
echo '===== CREATING ARCHIVE ====='
tar -czf Filie.tgz Filie.app
echo '===== UPLOADING ARCHIVE ====='
curl --upload-file Filie.tgz ftp://home-up.t-online.de/
echo '===== FINISHED ====='
Note that this script uses Tar/GZip, and thus can't cope with resource forks (though I've heard rumors that Tiger's command line tools have been changed to fix this). Also, you can use
man curl to find out what parameters to include to authenticate with the FTP server to which you're uploading if your ISP doesn't pre-authenticate you like mine does.
I've put most of these scripts into files in my central library so I can just call them from Xcode, and to avoid code duplication that would make maintenance hard. I'd be interested in hearing what kinds of scripts you are using.