How to add a Help Book to a Mac OS X Preference Pane

Manfred Stienstra

Normally you can register a Help Book in your Cocoa application by setting CFBundleHelpBookFolder and CFBundleHelpBookName in your Info.plist. When the application is launched the runtime automatically loads the Help Books based on this information.

When an application loads additional functionality from a plugin bundle as is the case with preference panes it doesn't automatically load Help Books from the plugin. The plugin needs to take care of this itself.

Authoring a Help Book is no different from a normal application. The developer documentation is a bit flakey here and there, in general it gives a good overview of how to do this. I assume you've succeeded in creating a Help Book and it's called MailServer.help. Make sure that it's copied over to the Resources/English.lproj/MailServer.help folder in your bundle.

Now you add our Help Book to the Info.plist as you would in a normal application.

<key>CFBundleHelpBookFolder</key>
<string>MailServer.help</string>
<key>CFBundleHelpBookName</key>
<string>Learn to use MailServer</string>

Newer versions of the Xcode plist editor show these keys as ‘Help Book directory name’ and ‘Help Book identifier’.

Note that the CFBundleHelpBookName has to match the title for the Help Book you specified in the main HTML file.

<meta name="AppleTitle" content="Learn to use MailServer">

If you want a specific part of the documentation to show up in the Help menu when the preference pane is loaded you can also define this in the Info.plist.

<key>NSPrefPaneHelpAnchors</key>
<array>
  <dict>
    <key>anchor</key>
    <string>mailserver_help_index</string>
    <key>title</key>
    <string>Learn to use MailServer</string>
  </dict>
</array>

You can define multiple anchors. They will open the Help Book near the anchor in your HTML.

<a name="mailserver_help_index"></a>

This anchor can reside anywhere in the Help Book. The Help Viewer knows where to find it using the help index you generated as part of the Help Book.

Now add the Help Book to your Xcode project as described in the documentation. If you did this properly it will show up in your application bundle in Contents/Resources.

To complete the magic summoning of the Help Books you register it with the Help Manager.

- (void) mainViewDidLoad {
  if (![[NSHelpManager sharedHelpManager] registerBooksInBundle:[self bundle]]) {
    NSLog(@"Failed to register the Help Book for MailServer.prefpane.");
  }
}

If this fails you're basically on your own. There are a few things you can try though. I've notice that both the Help daemon and the Help Viewer are rather needy when caching. Every time I changed anything to my code or to the bundle I made sure all the caches were gone and helpd was fresh.

$ sudo killall helpd
$ rm -Rf ~/Library/Caches/com.apple.help*

For a working example you can check out the Passenger Preference Pane project on GitHub.