Do you need help on a specific subject? Use the contact form (Request a blog entry) on the right hand side.

2015-06-19

Adding Apple help to an OS-X application

So this is not Swift related, but it is something many of us will encounter eventually: How to add Apple Help support to an application

I spend a full day trying to get this to work, and I failed. The document from Apple has errors in it, and there is precious little to find elsewhere on the inet. Though I did find one interesting blog entry on this here: Apple help in 2015. Unfortunately the hints and tips provided there also failed to work for me.

I did in fact give up after that. I took the alternative approach: connect the help menu to the AppDelegate and handle the help by opening up a html file that is located in the resources. Like this:

    @IBAction func displayHelp(sender: AnyObject?) {
        
        let url = NSBundle.mainBundle().URLForResource("help", withExtension: "html")
        
        NSWorkspace.sharedWorkspace().openURL(url!)

    }

Of course that worked... but it irked me. Why would the "normal" approach not work?

What I wanted was the most simple implementation that I could think of, no multi language support, no icon, no special features, no index file etc. Just a simple title with a few topics. I figured that when I can get that to work, the rest is a matter of legwork.

And then I had some luck... well, at least it finally started to make some sense after I read up on the Core Foundation Keys. With a little experimenting I finally had my first success.

Here is how it works for me:

First create the content, I created one main file (MyAppHelp.html) and a couple of topic files (Topic1.html, Topic2.html etc). The MyAppHelp.html linked to the Topic files in the usual way (<a href...)

In the MyAppHelp.html file I did not include anything special, no meta tags. Specifically no "AppleTitle" tag and no "Robots" tag. Just plain html content with links to the topic pages.

Next I created the folder hierarchy for the help book on my desktop and placed the html files in the Resources folder.


We need one more file, a property list. I simply copied a Info.plist from another app's help bundle and modified its content as follows:


The key's InfoDictionary version, Bundle OS Type code, Bundle creator OS Type code and HPDBookType should be exactly as above.

The HPDBookAccessPath should be the name of the top level html file. I think that if you put it in a subdirectory (e.g. English/MyAppHelp.html) the name of the subdirectory should be included, but in my example here just the name is sufficient.

The HPDBookTitle is important, it is used in the Info.plist of your application to identify the help book.

The Info.plist just created should reside at the Contents level of the help book hierarchy. The complete help book looks as follows:


Now rename the help book to create a bundle: MyAppHelp becomes MyAppHelp.help. When we do this, the icon changes to the Apple helpbook icon, and we can no longer simply open the folder. Remember that with Right-Click -> Show Package Contents we can still see what is inside.

Note: Even though the icon changed, this does not mean that we can double-click the help book to open it. That won't work. But it will work from within the application...

Now switch to the project in xcode. In Xcode select "Add Files" and choose the help book just created. Make sure that the files and folder structure is copied:


Almost done...
Now edit the Info.plist of the project to include the following two key's:


Forget about the "Help Book File" key, we don't need that.
It should be noted that the Help Book Identifier must have the same value as the HPDBookTitle from the help book Info.plist file. The Help Book directory name key is the name of the help book file that we added to the project.

That is it, launch the application and select "Help -> MyApp Help" from the menu. Voila!

PS: A neat trick is to create an alias into the Resources folder of the help book and place that somewhere at the top level of the project. Use that alias to quickly access the html files for updating etc. Also, most HTML editors will be unable to open a bundle, but they can follow an alias. Unfortunately Xcode will not see the modifications you make to the help book, but git will. So if you use git, the changes to the help book will be put in the repository, even if Xcode does not show the "M" behind the help book.

Happy coding...

Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH

We don't get the world we wish for... we get the world we pay for.

9 comments:

  1. Thanks for this post. I could only get help to work when I used the Bundle identifier of the help book as the help book identifier of the project. This is actually pretty nice, because then I can use a nice HDPBookTitle. Using the intervening en.lproj folder did not cause any problems. I did help indexing as well, but had to use "hiutil" at the command line since I didn't see Help Indexer. Likewise defining the icon in the plist with HPDBookIconPath relative to the Resources folder worked too... my icon shows up on the help query. Meanwhile, Apple seems to be using some new tools for help authoring!

    ReplyDelete
    Replies
    1. Help Indexer app has to be downloaded from the Apple developer site - it is part of an additional command line tool bundle (make sure you get the right version for your level of XCode).

      Delete
  2. Thanks for your comments John.
    Apple Help is very much a "moving target", I just wish Apple would provide some up-to-date documentation about it.

    ReplyDelete
  3. This comment has been removed by a blog administrator.

    ReplyDelete
  4. Got it working. the 'Content' folder must be 'Contents' -NOT singular

    ReplyDelete
  5. Would probably be useful to have a working toy example published in GitHub. That way discrepancies such as name of the Contents folder would have to be legitimate in a working example. Of course, if Apple Help is a rapidly moving target, then the toy example would get quickly out of date... and not many would want to maintain a toy example!

    ReplyDelete
  6. Thanks Kyle, as you can see I have corrected the examples in the post!

    ReplyDelete
  7. Hi Developer,
    could you please update this really useful post for Xcode 9.

    I'm trying to add an Help to my OSX app done under Xcode 9 without success.

    Thanks in advance.

    ReplyDelete
    Replies
    1. Due to circumstances I have not made the jump to Xcode 9 yet.
      Sadly I do not think that this is likely this year...

      Delete