How to migrate iOS API Reference from Doxygen to Jazzy

… and start supporting Swift. At Firebase, we moved our iOS API reference docs from Doxygen to Jazzy. Here are the issues we faced and the full migration guide.

Jazzy console output

Add comments for all interfaces, protocols, properties, methods, enums, structs, and typedefs

If you don’t have documentation for one of these elements, Jazzy will still include it in the output, marked as “undocumented”. You can use the --skip-documentation parameter with jazzy script to see which declarations in your public headers are missing documentation.

Causes Jazzy Error

@property(nonatomic, copy) NSString *someProperty;

Fix

/// This is a comment for someProperty.
@property(nonatomic, copy) NSString *someProperty;

Alternate Fix

///
@property(nonatomic, copy) NSString *someProperty;

Use documentation tags supported by Jazzy

Jazzy currently only supports the following documentation tags. Do not use @brief, @var, @enum, @protocol, @discussion, or @remarks as they are not currently supported by jazzy. To see the formatting for Quick Help in Xcode, press and hold the “option” key and click on the method name or property.

  1. @see
  2. @param
  3. @return
  4. <code></code creates a link to a constant, property, or method and should be used instead of @link (use <code></code with @see)
  5. <pre> instead of \code or @code
  6. </pre> instead of \endcode or @endcode

Fix

/// This is the description for a method.
///
/// @see <code>someProperty</code>
/// @see <code>-someMethod:</code>
///
/// <pre>
/// // This is a comment inside a code snippet.
/// // @code and @endcode are not currently supported by
/// // jazzy. Use <pre> and </pre> instead.
/// NSString *someString = [[NSString alloc] init];
/// </pre>
///
/// @param someParam1 This is a description for someParam1.
/// @param someParam2 This is a description for someParam2.
///
/// @return Description of the return value.
(NSString *)someMethodWithParam1:(NSString *)someParam1
param2:(NSString *)someParam2;

Alternate Fix

/**
* This is the description for a method.
*
* @see <code>someProperty</code>
* @see <code>-someMethod:</code>
*
* <pre>
* // This is a comment inside a code snippet.
* // @code and @endcode are not currently supported by
* // jazzy. Use <pre> and </pre> instead.
* NSString *someString = [[NSString alloc] init];
* </pre>
*
* @param someParam1 This is a description for someParam1.
* @param someParam2 This is a description for someParam2.
*
* @return Description of the return value.
*/
(NSString *)someMethodWithParam1:(NSString *)someParam1
param2:(NSString *)someParam2;

Add blank lines before and after the @param block

There needs to be a newline between the last description paragraph and the first parameter block. There also needs to be a newline before the @return block. Otherwise the parameters and return value show up in both the description (badly formatted).

Causes Jazzy Error

/**
* Use removeObserverWithHandle: to stop receiving updates.
* @param eventType The type of event to listen for.
* @param block The block that should be called with initial data.
* @return A handle used to unregister this block later.
*/

Fix

/**
* Use removeObserverWithHandle: to stop receiving updates.
*
* @param eventType The type of event to listen for.
* @param block The block that should be called with initial data.
*
* @return A handle used to unregister this block later.
*/

Use #pragma mark instead of @name

Do not use @name tags, they show up with the */ characters appended to the end in the Jazzy built files. Use #pragma mark instead.

Causes Jazzy Error

/** @name Attach observers to read data */

Fix

#pragma mark — Attach observers to read data

Use + instead of * in Markdown lists

Do not use * Markdown syntax to create bulleted lists, they won’t show up as lists and the * characters are left behind, making things look like pointers.

Causes Jazzy Error

/**
* To modify the data, set its value property to any of the native
* types support by Firebase Database:
* * NSNumber (includes BOOL)
* * NSDictionary
* * NSArray
* * NSString
* * nil / NSNull to remove the data
*/

Fix

/**
* To modify the data, set its value property to any of the native
* types support by Firebase Database:
*
* + NSNumber (includes BOOL)
* + NSDictionary
* + NSArray
* + NSString
* + nil / NSNull to remove the data
*/

Use HTML syntax for error-code lists

If you don’t, Jazzy puts them all together on one line. Also need a  character between the error code name and the description.

Causes Jazzy Error

@remarks Possible error codes:
- @c FIRAuthErrorCodeInvalidCustomToken Indicates a validation error with the custom token.
- @c FIRAuthErrorCodeCustomTokenMismatch Indicates the service account and the API key belong to different projects.

Fix

@remarks Possible error codes:
<ul>
<li>@c FIRAuthErrorCodeInvalidCustomToken — Indicates a validation error with the custom token.</li>
<li>@c FIRAuthErrorCodeCustomTokenMismatch — Indicates the service account and the API key belong to different projects.</li>
</ul>

Note: the <ul> must not have an empty line between it and the line above or it will end up in a separate <p> tag and not show bullets.


No @c tags inside @param or @return tags

They break the build.

Causes Jazzy Error

@param app The @c FIRApp for which to retrieve the associated @c FIRAuth instance.
@return The @c FIRAuth instance associated with the given @c FIRApp.

Fix

@param app The FIRApp for which to retrieve the associated FIRAuth instance.
@return The FIRAuth instance associated with the given FIRApp.

No smart quotes (“”)

They get passed through by Jazzy and cause warnings when you add the generated docs to a CL.

Causes Jazzy Error

“One account per email address”

Fix

"One account per email address"

Use nullable and nonnull in Objective-C public headers

Audit Objective-C public headers with nullability annotations for interoperability with Swift code. Simple pointers that can be nil in Objective-C should be annotated as nullable so that they are mapped properly to optional types in Swift.

Causes Swift to map everything to implicitly unwrapped optional

- (AAPLListItem *)itemWithName:(NSString *)name;

Fix

- (nullable AAPLListItem *)itemWithName:(nonnull NSString *)name;

For more information, see Nullability and Objective-C in the Apple Developer Blog.


Hide documentation for private/pre-release properties and methods with :nodoc:

Properties and methods sometimes make it into header files before you’re ready to document them. To skip documenting these properties or methods, add :nodoc: to their comment, like so:

/**
* A new authorization token that we’re not ready to document yet.
* :nodoc:
*/
@property(nonatomic, copy) NSString *authToken;