Sign in Join
Wiki copytemporary

Add an Apple Help Book to your macOS app: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11*(macOS only)*
22
33No professional macOS application should be without a functioning Apple Help Book. Unfortunately Apple make it harder than it should be for developers to create an Apple Help Book because the official documentation is significantly out of date (2013 anyone?) and the Apple Help Viewer has undergone significant change in recent versions of the operating system. For the full details on how to add an Apple Help Book to your application, along with sample code, read on.
44
55## Application Bundle Layout
66
77A typical [[Application Bundle|application bundle]] with an Apple Help Book bundle should resemble this layout:
88
9-`+-- MyApp.app/                                                  [application bundle]`\
10-`     |`\
11-`     +-- Contents/`\
12-`           |`\
13-`           +-- MacOS/`\
14-`           |     |`\
15-`           |     +-- MyApp                                      [application executable]`\
16-`           +-- Resources/`\
17-`           |     |`\
18-`           |     +-- MyApp.icns`\
19-`           |     |`\
20-`           |     +-- MyApp.help/                                [Help Book bundle]`\
21-`           |           |`\
22-`           |           +-- Contents/`\
23-`           |                 |`\
24-`           |                 +-- Resources/`\
25-`           |                 |     |                               `\
26-`           |                 |     +-- en.lproj/                [for English]`\
27-`           |                 |     |     |`\
28-`           |                 |     |     +-- help.helpindex     [generated by the macOS help indexer hiutil]`\
29-`           |                 |     |     |`\
30-`           |                 |     |     +-- index.html         [table of contents - do not index]`\
31-`           |                 |     |     |`\
32-`           |                 |     |     +-- page1.html`\
33-`           |                 |     |     |`\
34-`           |                 |     |     +-- ...`\
35-`           |                 |     |     |`\
36-`           |                 |     |     +-- pageN.html`\
37-`           |                 |     |     |`\
38-`           |                 |     |     +-- InfoPlist.strings  [see `[[macOS property list files|Localizing an Info.plist]]`]`\
39-`           |                 |     |`\
40-`           |                 |     +-- fr.lproj/                [for French] `\
41-`           |                 |     |     |`\
42-`           |                 |     |     +-- help.helpindex     [generated by the macOS help indexer hiutil]`\
43-`           |                 |     |     |`\
44-`           |                 |     |     +-- index.html         [table of contents - do not index]`\
45-`           |                 |     |     |`\
46-`           |                 |     |     +-- page1.html`\
47-`           |                 |     |     |`\
48-`           |                 |     |     +-- ...`\
49-`           |                 |     |     |`\
50-`           |                 |     |     +-- pageN.html`\
51-`           |                 |     |     |`\
52-`           |                 |     |     +-- InfoPlist.strings `\
53-`           |                 |     |`\
54-`           |                 |     +-- images/          `\
55-`           |                 |     |     |`\
56-`           |                 |     |     +-- chip3_32x32.ico    [icon used in help pages]`\
57-`           |                 |     `\
58-`           |                 +-- Info.plist                     [Help Book plist]`\
59-`           |`\
60-`           +-- Info.plist                                       [application plist]`
9+```
10++-- MyApp.app/ [application bundle]
11+ |
12+ +-- Contents/
13+ |
14+ +-- MacOS/
15+ | |
16+ | +-- MyApp [application executable]
17+ +-- Resources/
18+ | |
19+ | +-- MyApp.icns
20+ | |
21+ | +-- MyApp.help/ [Help Book bundle]
22+ | |
23+ | +-- Contents/
24+ | |
25+ | +-- Resources/
26+ | | |
27+ | | +-- en.lproj/ [for English]
28+ | | | |
29+ | | | +-- help.helpindex [generated by the macOS help indexer hiutil]
30+ | | | |
31+ | | | +-- index.html [table of contents - do not index]
32+ | | | |
33+ | | | +-- page1.html
34+ | | | |
35+ | | | +-- ...
36+ | | | |
37+ | | | +-- pageN.html
38+ | | | |
39+ | | | +-- InfoPlist.strings [see Localizing an Info.plist]
40+ | | |
41+ | | +-- fr.lproj/ [for French]
42+ | | | |
43+ | | | +-- help.helpindex [generated by the macOS help indexer hiutil]
44+ | | | |
45+ | | | +-- index.html [table of contents - do not index]
46+ | | | |
47+ | | | +-- page1.html
48+ | | | |
49+ | | | +-- ...
50+ | | | |
51+ | | | +-- pageN.html
52+ | | | |
53+ | | | +-- InfoPlist.strings
54+ | | |
55+ | | +-- images/
56+ | | | |
57+ | | | +-- chip3_32x32.ico [icon used in help pages]
58+ | |
59+ | +-- Info.plist [Help Book plist]
60+ |
61+ +-- Info.plist [application plist]
62+```
6163
6264## Main Menu
6365
6466If you have not already done so, you need to add a TMainMenu component to your application form, and create a TMenuItem with a caption name of "Help". macOS will then automatically add a Search menu option to your Help menu when you run your application.
6567
6668You also need to add a menu item to your Help menu to open your application help file at its table of contents. Once you have added the My App Help menu item, create an OnClick event handler containing the following code:
6769
6870``` pascal
6971...
7072Uses
7173 LCLIntf, MacOSAll;
7274...
7375function GetResourcesPath(): string;
7476var
7577 pathRef: CFURLRef;
7678 pathCFStr: CFStringRef;
7779 pathStr: shortstring;
7880begin
7981 pathRef := CFBundleCopyBundleURL(CFBundleGetMainBundle());
8082 pathCFStr := CFURLCopyFileSystemPath(pathRef, kCFURLPOSIXPathStyle);
8183 CFStringGetPascalString(pathCFStr, @pathStr, 255, CFStringGetSystemEncoding());
8284
8385 Result := pathStr + '/Contents/Resources/';
8486end;
8587
8688procedure TForm1.MenuItem_MyAppHelpClick(Sender: TObject);
8789var
8890 helpPath: String;
8991begin
9092 helpPath := GetResourcesPath + 'MyApp.help';
9193 OpenDocument(helpPath);
9294end;
9395```
9496
9597> **Tip:** If you wish to **NOT** have macOS automatically add a Search option to your Help menu then, when you create the Help menu item, add a trailing space after Help in the menu item's caption property and the Search option will not show up in your application's Help menu.
9698
9799## Application Info.plist
98100
99101One of the most important files is the application [[macOS property list files|Info.plist]]. Two keys need to be added or Spotlight will not index your help file. If your help file is not indexed, then even trying to open it will result in a perplexing "Not available" error page in the Apple Help Viewer. If you are using Xcode, then add these keys.
100102
101-` Help Book directory name`\
102-` Help Book identifier`
103+```
104+ Help Book directory name
105+ Help Book identifier
106+```
103107
104108The Help Book directory name should refer to the Help Book bundle name (eg MyApp.help). This directory should be located in the application bundle Contents/Resources directory. The Help Book identifier is simply the name of your help (eg My App Help).
105109
106110If you are editing the `Info.plist` file in a text editor, then add these keys and their value strings:
107111
108112``` xml
109113 <key>CFBundleHelpBookFolder</key>
110114 <string>myapp.help</string>
111115 <key>CFBundleHelpBookName</key>
112116 <string>My App Help</string>
113117```
114118
115119## Help Book Info.plist
116120
117121Below is a basic Help Book Info.plist for an application called "My App".
118122
119123``` pascal
120124<?xml version="1.0" encoding="UTF-8"?>
121125<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
122126<plist version="1.0">
123127<dict>
124128 <key>CFBundleDevelopmentRegion</key>
125129 <string>en</string>
126130 <key>CFBundleIdentifier</key>
127131 <string>org.sentry.myapp.help</string>
128132 <key>CFBundleInfoDictionaryVersion</key>
129133 <string>6.0</string>
130134 <key>CFBundlePackageType</key>
131135 <string>BNDL</string>
132136 <key>CFBundleShortVersionString</key>
133137 <string>22</string>
134138 <key>CFBundleSignature</key>
135139 <string>hbwr</string>
136140 <key>CFBundleVersion</key>
137141 <string>22</string>
138142 <key>HPDBookAccessPath</key>
139143 <string>index.html</string>
140144 <key>HPDBookIconPath</key>
141145 <string>images/chip3_32x32.ico</string>
142146 <key>HPDBookIndexPath</key>
143147 <string>help.helpindex</string>
144148 <key>HPDBookTitle</key>
145149 <string>My App Help</string>
146150 <key>HPDBookType</key>
147151 <string>3</string>
148152 <key>HPDBookUsesExternalViewer</key>
149153 <false/>
150154</dict>
151155</plist>
152156```
153157
154158## Creating Help Book pages
155159
156160Apple Help Book pages are simply HTML files. You need to create an `index.html` page which is the table of contents for your application Help Book. You also need to ensure that this file is not indexed or it will show up in the Apple Help Viewer as a blank entry. There is also usually little point indexing pages which just contain links to other pages. You do this by adding the noindex meta tag to the file. Here is an example `index.html` page for "My App".
157161
158162``` html
159163<?xml version="1.0" encoding="UTF-8"?>
160164<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">
161165
162166<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
163167<head>
164168 <title>My App Table of Contents</title>
165169 <meta name="robots" content="noindex">
166170</head>
167171
168172<body class="Normal">
169173
170174 <H1><img style="margin: 0.0px 12.0px 0.0px 0.0px;" height="32.0" src="../images/chip3_32x32.ico" width="32.0" />Table of Contents</H1>
171175
172176 <ul>
173177 <li id="Page1"><a href="Page1.html">Introduction</a></li>
174178 <li id="Page2"><a href="Page2.html">Combo Boxes</a></li>
175179 </ul>
176180
177181</body>
178182</html>
179183```
180184
181185A sample page 1 for "My App" is set out below. Note:
182186
183187``` html
184188<?xml version="1.0" encoding="UTF-8"?>
185189<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">
186190
187191<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
188192 <head>
189193 <title>Introduction</title>
190194 <meta name="robots" content="index, anchors" />
191195 <meta name="description" content="My App Introduction" />
192196 <meta name="keywords" content="introduction, operating system" />
193197 </head>
194198 <body>
195199 <a name="Introduction"></a>
196200 <H1><img style="margin: 0.0px 12.0px 0.0px 0.0px;" height="32.0" src="../images/chip3_32x32.ico" width="32.0" />Introduction</H1>
197201 <p>My App is a very useful application for all users of all ages!</p>
198202 <p>The macOS version of My App has been tested on macOS Sierra 10.12.6 , macOS High Sierra 10.13.6 and macOS Mojave 10.14.5.</p>
199203 <p>The Windows version of My App has been tested on Windows XP, Windows 7 and Windows 10.</p>
200204
201205 <p>The latest version of the My App application is available from the web site at <a href="https://www.sentry.org/">www.sentry.org</a>.</p>
202206 </body>
203207</html>
204208```
205209
206210Once you have created the HTML pages for your Help Book, you need to index them. You do this from a Terminal using the macOS command line utility called `hiutil`. The man page (`man hiutil` in an Applications \> Utilities \> Terminal) details all the information you may ever need to know. A simple example to create an index file and include anchors:
207211
208212```text
209213 hiutil -Caf help.helpindex .
210214```
211215
212216This will index all the HTML files in the current directory and create the index file named helpindex.help in the same directory (do not omit the trailing full stop which signifies the current directory). It will also index any help anchors should you use them for context-sensitive help; note that macOS applications rarely, if ever, implement context-sensitive help.
213217
214218An example of a help anchor is included in the sample page 1 HTML file above; specifically the: `<a name="Introduction"></a>` line.
215219
216220Also note the
217221
218222line which ensures that the anchors are indexed along with the file content.
219223
220224## Updating cached Help Books
221225
222226macOS caches an Apple Help Book after first use which can be perplexing when you are developing a Help Book and do not see your changes. The way to overcome this is to run the following shell script from a Terminal after a change:
223227
224228``` bash
225229#!/bin/sh
226230killall helpd
227231rm -rf ~/Library/Caches/com.apple.help*
228232rm -rf ~/Library/Preferences/com.apple.help*
229233```
230234
231235Note: those are tildes (~) and not dashes (-) before /Library; this only affects the current user's Apple Help cache and Apple Help preferences, not the system-wide ones.
232236
233237## Sample MyApp with Help Book
234238
235239The Apple Help Book facility can be frustrating the first time you set out to create an Apple Help Book. In an effort to make it a little easier, you can download a minimal "My App" example (blank form with Main Menu and Help Menu) on which the above examples have been based. Note: the first time you run MyApp.app and choose the Help Menu, no entries will show in the Search if you start typing "my app" apart from the menu items. Give it a few seconds and delete the "my app" in the search box and the two sample entries should show up in a few seconds after you again type "my".
236240
237241![](/wiki-images/3/3a/MyAppMenu.png)
238242
239243Compiled MyApp: [Download](https://www.sentry.org/lazarus/MyApp.zip) (2.2MB).
240244
241245Full project source code is available from [SourceForge](https://sourceforge.net/p/lazarus-wiki-projects/code/ci/master/tree/laz_helpbook/).
242246
243247## See also
244248
245249- [[Application Bundle|macOS Application Bundle]]
246250- [[macOS property list files]]
247251
248252---
249253*From the Free Pascal wiki, page "Add an Apple Help Book to your macOS app", as it stood on 2021-12-28 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
250254Category: Code Snippets
251255Category: Help and Docs
252256Category: Platform-sensitive development
253257Category: Tutorials
254258Category: macOS

Back to history