How to generate documentation in Swift with Jazzy

in Swift

How to generate documentation for Swift projects in Jazzy


In this tutorial we are going to talk about how to automatically create documentation for your framework, pod or library written in Swift matching Apple’s official reference documentation without writing a single line of code outside Xcode. For the sake of having some code we are going to create a simple class which will present several different types of alerts and dialogs. Then we will create documentation for that class using Jazzy, which is an open source project developed by guys from Realm. Result will be a bunch of HTML files which look almost exactly like the documentation Apple has for its frameworks.

Creating a new project

Open your Xcode and create  a new Coca Touch Framework project. The option should be under iOS/Frameworks & Libraries.Although Jazzy supports Objective-C as well, make sure you select Swift as a language because that’s what we will focus on in this tutorial. Xcode will generate one very basic and clean project with only few files in it, which is exactly what we need.

Cocoa Touch framework template in Swift

Cocoa Touch framework template in Swift

Implementing Alerts class

Next, we are going to create one simple class just so we have some code to work with. Create a new empty Swift file and name it Alerts. Here we are going to put three methods here, two private and one public, which will be enough to start playing with Jazzy. Our methods will simply generate various types of alerts or action sheets depending on alert style. Hence, the implementation of these methods should look something like this:

import Foundation
import UIKit

class Alerts {
    
    func showAlert(view: UIViewController, title: String, message: String, style: UIAlertActionStyle) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
        setAction(alert, style: style)
        view.presentViewController(alert, animated: true, completion: nil)
    }
    
    func showActionSheet(view: UIViewController, title: String, message: String, style: UIAlertActionStyle) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.ActionSheet)
        setAction(alert, style: style)
        view.presentViewController(alert, animated: true, completion: nil)
    }
    
    private func setAction(let alert: UIAlertController, style: UIAlertActionStyle) {
        switch style {
        case .Default:
            alert.addAction(UIAlertAction(title: "Ok", style: .Default, handler: nil))
            
        case .Cancel:
            alert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
            
        case .Destructive:
            alert.addAction(UIAlertAction(title: "Destroy", style: .Destructive, handler: nil))
        }
    }
    
}

 

There’s a reason we have two public and one private method and you’ll see why in few minutes. You may also notice that the code in showAlert and showActionSheet is quite similar and that we could probably put that in a single method and just pass an alert type as a property, but again, the code is not the focus of this tutorial so we’ll just leave it as it is. Feel free to experiment and add perhaps something else in addition to what we’ve implemented so far.

Writing comments

In order to use the full potential of Jazzy and to make sure all classes, methods and variables are well documented, special attention has to be given to writing comments. I will mention few most common styles and techniques but if you are interested in fine details there’s a whole chapter on Apples Official docs. Here is one basic example of how to comment a method in Swift:


/**
	<#Description#>

	- parameter view:    <#view description#>
	- parameter title:   <#title description#>
	- parameter message: <#message description#>
	- parameter style:   <#style description#>
*/

 

This can be quite time consuming if you have a method with a lot of parameters, or maybe some callbacks. Fortunately Xcode has some great packages for auto generating comments, and from Xcode 8 Apple integrated a comment documentation generator plugin, which is built on top of VVDocumenter, which was my favorite plugin for generating comments. If you don’t like Apple’s new built in document generator feature, feel free to explore Alcatraz in order to find something suitable for your needs.

Let’s now add few comments to our code. I will also add pragma marks to distinguish between public and private methods in our Alerts class. The final product should look something like this:

import Foundation
import UIKit

/// Generates alerts and action sheets
public class Alerts {
    
    // MARK: Public methods 
    
    /**
     Displays alert over current view controller.
     
     - parameter view:    View over which the alert is presented. Should use self, or if called from viewDidLoad() method, root view controller.
     - parameter title:   Title of the alert
     - parameter message: Main message presented in the alert
     - parameter style:   Type of alert action. Refer to UIAlertActionStyle enum in Apple docs.
     */
    public func showAlert(view: UIViewController, title: String, message: String, style: UIAlertActionStyle) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
        setAction(alert, style: style)
        view.presentViewController(alert, animated: true, completion: nil)
    }
    
    /**
     Displays action sheet over current view controller.
     
     - parameter view:    View over which the action sheet is presented. Should use self, or if called from viewDidLoad() method, root view controller.
     - parameter title:   Title of the action sheet
     - parameter message: Main message presented in the action sheet
     - parameter style:   Type of action sheet action. Refer to UIAlertActionStyle enum in Apple docs.
     */
    public func showActionSheet(view: UIViewController, title: String, message: String, style: UIAlertActionStyle) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.ActionSheet)
        setAction(alert, style: style)
        view.presentViewController(alert, animated: true, completion: nil)
    }
    
    // MARK: Private methods 
    
    /**
     Sets the default action of the given alert or action sheet
     
     - parameter alert: Alert controller to which the action is applied
     - parameter style: Action style. Refer to UIAlertActionStyle enum in Apple docs.
     */
    private func setAction(let alert: UIAlertController, style: UIAlertActionStyle) {
        switch style {
        case .Default:
            alert.addAction(UIAlertAction(title: "Ok", style: .Default, handler: nil))
            
        case .Cancel:
            alert.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
            
        case .Destructive:
            alert.addAction(UIAlertAction(title: "Destroy", style: .Destructive, handler: nil))
        }
    }
}

 

Note that we had to add public keyword to the class and every method for which we want to create the docs. We are now ready to generate the documentation. As I mentioned at the begining of this article, we will be using Jazzy, an open source project developed by guys from Realm. You can find the source code at GitHub but the installation and usage is straightforward and easy. First, we have to install Jazzy, so fire up your terminal and write :

 [sudo] gem install jazzy 

 

If the installation fails, make sure you update your RubyGem to the latest version as the package itself requires Ruby 2 or greater. Some ElCapitan users had issues with gem so if you’re one of them instead of typing gem install in your terminal, type the following:

sudo gem install -n /usr/local/bin GEM_NAME_HERE

 

If you’re missing some other dependencies such as CocoaPods installing jazzy will also pull those updates as well. The reason why the first command does not work is because  of the new System integrity protection feature introduced in El Capitan which restricts even administrators from writing to /usr/bin. After the installation process is completed, navigate to your project using terminal and simply type jazzy inside your project root directory. You should see something like this:

Example of Jazzy successfully generating docs

Example of Jazzy successfully generating docs

Navigate to your Xcode project and you should see a completely new folder called docs. Inside there are a bunch of HTML and JS files but you should simply open index.html and the entire documentation should popup. Example is given below:

Jazzy documentation example

Jazzy documentation example

We now clearly see the description of the class itself, table with every method we implemented, and detailed description of each property it accepts as an input. Cool isn’t it? But what about that one private method we also created? Jazzy by default generates documentation only for the classes and methods which are explicitly declared as public, which is why we had to add public keyword to the class itself and the methods. However, you also have an option to generate docs for the private parts of your code as well. Instead of just typing jazzy in your terminal you can pass few parameters which will override the default behaviour. Hence, if you want private methods in your docs run:

jazzy --min-acl private

This will generate the same docs folder as you saw before but now inside your Alerts class you should see two sections, private and public, something like this:

Jazzy private docs

Jazzy private docs

And that’s it. That’s how you can easily generate documentation for your Swift project using open source package called Jazzy. Similar procedure would be if you used Objective-C instead of Swift, as the package supports both iOS languages. If you explore a bit more, you’ll notice that there are few styles and themes to choose from, hence you don’t have to stick to the default Apple-like template. I hope you found this tutorial useful and if you have any questions or comments, feel free to write in the comments or send me a message on Facebook, Twitter or LinkedIn.


  • Michael David McKenna

    Anybody have a method for deploying this documentation without using GitHub Pages? Pages only supports public pages and I would like to host our team’s internal iOS documentation.