API Documentation

This post discusses generating documentation from annotated source code. There are many tools available – I like appledoc from GentleBytes because it generates documentation that closely mimics Apple’s style and also creates and installs Xcode docsets. Refer to the GentleBytes page for basic setup and usage information. Read on for details of how I implement appledoc in my projects and why.

Source Code Management (SCM) Integration

I like to put the API Documentation (and other “external” documentation) under version control for all the same reasons we put source code under version control. I create a separate high-level folder “Documentation” in all my projects for this purpose.

Side note – while my personal projects usually have very little in the Documentation folder besides the API documentation, my commercial projects have various requirements (usually Word or Excel), art (Photoshop), content (Excel), and so on. Even though you can’t do a “diff” on most of these files, I find having the history to be incredibly useful.

I’ve used both Subversion and Git – neither likes it when entire folder structures are deleted and re-added, as appledoc does every time you generate new documentation. To work-around this my script (see below) has appledoc generate the documentation in a tmp folder outside the scope of the SCM, and then use rsync to synchronize any existing files in the Documentation/html folder – thus avoid the mass delete and re-add that causes problems for SCMs.

The configuration and script below are SCM-friendly.

Configuring appledoc

As discussed on the GentleByte site and particularly in Cocoanetics post, you have several options about how you pass configuration parameters to appledoc. I prefer passing them directly from the Run Script phase of my GenDocumentation target – mostly because I hate the plist editor in Xcode. My script is pretty generic, I just copy the following script from an existing project.

#appledoc Xcode script
# Start constants
company="OMaraConsultingAssociates";
companyID="com.omaraconsultingassoc";
companyURL="http://omaraconsultingassoc.com";
target="iphoneos";
#target="macosx";
outputPath="/tmp/appledoc";
# End constants
/usr/local/bin/appledoc \
--project-name "${PROJECT_NAME}" \
--project-company "${company}" \
--company-id "${companyID}" \
--docset-atom-filename "${company}.atom" \
--docset-feed-url "${companyURL}/${company}/%DOCSETATOMFILENAME" \
--docset-package-url "${companyURL}/${company}/%DOCSETPACKAGEFILENAME" \
--docset-fallback-url "${companyURL}/${company}" \
--output "${outputPath}" \
--publish-docset \
--docset-platform-family "${target}" \
--logformat xcode \
--keep-intermediate-files \
--no-repeat-first-par \
--no-warn-invalid-crossref \
--ignore "*.m" \
--exit-threshold 2 \
--index-desc "${PROJECT_DIR}/README.md" \
"${PROJECT_DIR}"
echo "Build successful, copying to project folder "
echo ${PROJECT_DIR}/Documentation
rsync -rv ${outputPath}/html ${PROJECT_DIR}/Documentation

Again, look to the GentleByte page for detailed information about the most of the above. I’ve done a few things that bear additional discussion:

  • in the constants, I declare an outputPath that is outside the scope of my SCM. That avoids the problem of deleting and re-adding folder structures mentioned above.
  • notice the –output “${outputPath}” configuration parameter. This causes appledoc to write the html files to the folder I declared in the constants, again – outside the control of the SCM.
  • I set¬† –exit-threshold 2 so the script ends if there are warnings. This prevents updating the SCM controlled ${PROJECT_DIR}/Documentation folder with undesirable output.
  • I always use a README.md file from GitHub, and always include it in the generated documentation via the –index-desc “${PROJECT_DIR}/README.md parameter.
  • the last line “rsync’s” the generated documentation from my¬†outputPath (outside the SCM) into the Documentation folder under control of the SCM. The rsync comand will create, update, and/or delete files and folders as necessary to synchronize the target folder from the source. As it does not delete and re-add the same files and folders, the SCMs I’ve worked with handle it as expected.

 

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>