Thứ Ba, 3 tháng 2, 2015

Documenting Your Objective-C and Swift Code in Xcode with HeaderDoc and Doxygen

63 Flares 63 Flares ×

During the development of an application there are various steps involved in the whole process. Some of them are the definition of its specifications, the creation of graphics, the implementation, and the testing phase following the implementation. Writing the code maybe consists of the most important part, as this brings the application to life, but further than that, equally important is the proper documentation of the code. No matter how well-written the code is, if there’s lack of a good documentation accompanying it, future troubles it’s possible to arise. Unfortunately, many developers overlook or ignore the importance of the code documentation, and that’s really bad, as good software is not just good code. It’s more than that.

When talking about documentation, apparently I don’t mean just to add a few lines of comments somewhere in the implementation files. It’s definitely more than that. But first, why is it such a big deal to document the code? Well, there are two cases: Whether you’re working on your own, or you are a part of a team. Let’s see in short each one.

xcode-macbook-featured

If you are the only developer of the under-development application, then it’s reasonable to believe that writing code documentation costs in time, so skipping doing that will bring you right into your target much sooner. Additionally, it’s easy to convince yourself that as you’re the sole developer there’s really no need to do that. But trust me, that’s the worst decision you might make during the app creation period. Suppose that you successfully implement the application, you sell it either on the app store or in a client of yours, and then you put it in the shelf. And after six months or so, you must create a new version of it by adding new features. When you open the project again and look to the existing code, a long before you write the first new line, you realize one killing truth: That you don’t remember almost anything! It’s hard to remember what you did, how you did it, and why! You must follow the one, painful way to wake that project up in your mind, which is no other than taking the project from the beginning and trying to “decode” your implementation line by line. Just a few comments here and there are not helpful, and eventually you end up making a super-effort for a long time until you understand everything. Many of you that you are now reading these lines may have come to that point, and I ensure you that there were times that I’ve been there too. This case is a real nightmare, and you often want to start building the project from scratch. And of course, the scenario described here would just be a… scenario, if we all invested a little time to write proper code documentation.

On the other hand, if you’re working on a project as a member of a team, then avoiding documenting your code would be catastrophic. When you share code with other developers, you must explain up to a point what you do (in the code) and how you do it, and of course other developers are required to do that too. There’s no case developers in big projects to fully understand the code of other fellow developers, as among all, that leads to unneeded waste of time. So, writing documentation in this case it’s like some sort of communication, but also an assistance to other members of the team to get the meaning of your code. After all, each programmer writes code differently than others, so making clear all the points of your code is a must-do task.

So, hoping that I’ve made my point, let me carry on by saying that the proper documentation and commenting regards all programming languages and all platforms. No matter whether you write apps for iOS, web or desktop systems: The point is that you should document as you go, so it’s easy for you (and everyone else) to revise your code really easy and without much effort.

As you understand, in this tutorial I am going to highlight the most important aspects of the code documentation. I’m going to talk for both Objective-C and Swift, as there are developers writing apps in both languages, and of course I’m planning to show you what the similarities and differences between those two languages are. Furthermore, I’ll show you how to produce full, web-based documentation for your app, but I’m afraid that I have to say that this is still an option for the Objective-C only.

As an iOS developer using the Xcode IDE, you might have been thought that the documenting possibilities would be the same for both languages. That’s not the case though, as Swift supports too few documenting options, compared always to the Objective-C, at least at the time of the writing of this post. However, they both give you enough “supplies” so you can write nice documentation. We will begin with Objective-C, as there are more than enough things to say there, and we’ll close this tutorial with code documentation in Swift. There is no need to get in more details now, as we’ll see them in the next parts.

Before we begin, let me note two last things. First, I’m not trying to make you mad about documentation, just to convince you that writing proper comments will improve your programming life. Second, writing code documentation it’s just a habit you have to adopt, and definitely it’s not a waste of time.

Creating a Demo App in Objective-C

Let’s get started by creating a new project in Objective-C, which we will use as the testing base for what we are going to see next. If you haven’t done yet, launch Xcode and create a new project. As we are not going to create a real demo application, selecting the Single View Application is just fine.

In the next step, name the project DocDemoObjC, and make sure to select the Objective-C option in the Language drop down menu:

t28_2_new_project_ObjC_2

Get finished with the guide by selecting a directory in your drive to save the project.

Documentation Specifics

As you know, the simplest way to write a comment in both Objective-C and Swift is to use the two slashes as shown below:

1
// This is a comment.

You can (and must) place anywhere in your code comments like that, so you clarify each part of it. However, when talking about code documentation, definitely I am not talking about the above notation. It would be pointless after all to devote a whole tutorial to that only. Code documentation regards a structured way to write comments using special keywords, also named tags, and marking the comments area with special characters, so the compiler perfectly understands it. There are a few simple rules that should be followed only. The result of all that is that your documentation can be displayed in three different places:

  1. In the Quick Help Inspector of the Utilities panel.
  2. In the Help Popup that is displayed when you press the Option key and click on the name of method, class or property.
  3. In the code-completion popup.

Additionally, proper code documentation enables you to produce complete HTML documentation for your app using various tools, such as the HeaderDoc and Doxygen. We’ll talk about both of them later, and we’ll see how you can do what I just said.

With all the above in mind, it’s time to make one more step further and say that there are three possible ways to mark a documentation area when writing code in Objective-C:

  1. To include your comments in a /** – */ block.
  2. To include your comments in a /*! – */ block.
  3. To begin each commented line with three slashes: ///

In our examples in this tutorial we are going to use the second way to write our documentation. I’m choosing this way for two reasons: First, it’s the only one recognised by HeaderDoc, and if the comment blocks don’t begin with that, no help pages will be created. At second, even though Doxygen prefers the first way, it also recognises this too. So, it’s going to suit us in both cases. The third commenting style is usually used when documenting single lines, such as properties, but still, we’re going to stick to the second option.

Now, there are specific keywords (or tags) you can use when writing documentation. Tags are divided in two categories: The first one regards top level tags, which they can be used to specify what kind of code exactly is commented, such as classes, structs, files, etc. Note that top level tags are not required to be used, but definitely help exporting tools (such as HeaderDoc and Doxygen) to create better results. In the second category exist the second level tags, which specify each details for each part of the documentation block. This kind of tags is actually what you need, as each one of them define another documentation part.

Right next I give you the most important second level tags, but note that they’re not just them. We’ll see a few top level tags later. What I list is what is mostly used:

  • @brief: Use it to write a short description about the method, property, class, file, struct, or enum you’re documenting. No line breaks are allowed.
  • @discussion: Use it to write a thorough description. You can add line breaks if needed.
  • @param: With this you can describe a parameter of a method or function. You can have multiple such tags.
  • @return: Use it to specify the return value of a method or function.
  • @see: Use it to indicate other related method or functions. You can have multiple such tags.
  • @sa: Similar to the previous one.
  • @code: With this tag, you can embed code snippets in the documentation. When viewing the documentation in Help Inspector, the code is represented with a different font, inside a special box. Always use the @endcode tag when you finish writing code.
  • @remark: Use it to highlight any special facts about the code you’re currently documenting.

You can find a full list of all supported tags here.

Note that the @ character is a prefix to each tag. Also, you can use special switches inside text, so you change its style and formatting. For example, the <b>Text</b> will make the Text word bold, while the <i>Text</i> will make the Text italic. It’s also interesting that you can represent part of the text as code (not a code snippet), if you write @cText. This will result to a different font formatting when the help is displayed in Xcode.

Alternatively to the above, you can replace the @ symbol with the backslash (\). That way the tags will be represented like this: \brief, \param, \return, etc. Note that the backslash is mostly used by the Doxygen documenting system, while the @ is used by the HeaderDoc. Here we’ll use everywhere the @, as it’s compatible with both documenting systems.

Code Documentation in Objective-C

Let’s see now how everything I mentioned above is used. Open the ViewController.m file, and in the private section of the class add the next property:

1
2
3
4
5
@interface ViewController ( )

@property (nonatomic, strong ) NSString *myName;

@end

Now, document it as shown next:

1
2
/*! @brief This property knows my name. */
@property (nonatomic, strong ) NSString *myName;

Go then to the viewDidLoad method, and start typing it. You will see that in the code completion popup the description we just wrote is there!

xcode autocomplete

But not only. While holding down the Option key in your keyboard, click on the myName property name to let the help popup come up:

t28_4_myname_help_popup

Even more, if you open the Help Inspector in the Utilities panel, you’ll find the same documentation there too:

Help inspector

Note that in the above comment the @brief tag could be omitted without any problem at all, as it’s inferred. That means that the next comment is valid as well:

1
2
/*! This property knows my name. */
@property (nonatomic, strong ) NSString *myName;

Also, the next notation is equal too:

1
2
/** This property knows my name. */
@property (nonatomic, strong ) NSString *myName;

And this is also equal:

1
2
/// This property knows my name. */
@property (nonatomic, strong ) NSString *myName;

Let’s see a first, easy example on how to document methods. At this point you must acknowledge that if your goal is to produce an HTML documentation, then only the documentation in the public methods (the header .h files) is visible. Whatever you write in the private parts of your classes is still visible in Xcode help, but no implementation is exported to the documentation. So, knowing that, let’s define a public method in the ViewController.h file:

1
2
3
4
5
@interface ViewController : UIViewController

- ( float )toCelcius : ( float )fromFahrenheit;

@end

Obviously, this method is going to convert the given Fahrenheit degrees to Celsius. Let’s add its documentation now:

1
2
3
4
5
6
7
8
9
10
11
12
/*!
    @brief It converts temperature degrees from Fahrenheit to Celsius scale.

    @discussion This method accepts a float value representing the temperature in <b>Fahrenheit</b> scale and it converts it to the <i>Celsius</i> scale.

                To use it, simply call @c[self toCelsius: 50];

    @param  fromFahrenheit The input value representing the degrees in the Fahrenheit scale.

    @return float The degrees in the Celsius scale.
 */

- ( float )toCelcius : ( float )fromFahrenheit;

Note that above we use the and HTML switches to make the included words bold and italic respectively. Also notice how we mark the inline code using the @c switch.

To see in the Xcode help how that documentation looks, open the ViewController.m file and define the method:

1
2
3
- ( float )toCelcius : ( float )fromFahrenheit {
    return (fromFahrenheit - 32 ) / 1.8;
}

Then place the caret on the method’s name, and look in the Quick Help Inspector:

t28_6_method1_help_inspector

You see that Xcode properly formats each part of the documentation. Here’s the same in the help popup (Option + Click on the method’s name):

t28_7_method1_help_popup

If you call it in the viewDidLoad method, then you can see the brief description in the code-completion popup:

method call pop over

Great, isn’t it? Just imagine how helpful and self-explaining your code can be that way, especially if you’re working with other people in a team.

To make this example even more interesting, let’s add one more public method that will do the exact opposing thing: Conversion from Celsius to Fahrenheit. Open the ViewController.h file, and add the next method declaration, along with its documentation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*!
    @brief It converts temperature degrees from Celsius to Fahrenheit scale.

    @param  fromCelcius The celsius degrees value.

    @return float The degrees in the Fahrenheit scale.

    @code
        float f = [self toCelsius:80];
    @endcode

    @remark This is a super-easy method.
 */

- ( float )toFahrenheit : ( float )fromCelcius;

In the above snippet we added two new tags: The @code – @endcode pair, and the @remark. You’ll see how they’re displayed right next.

Let’s go to implement the method in the ViewController.m file:

1
2
3
- ( float )toFahrenheit : ( float )fromCelcius {
    return fromCelcius * 1.8 + 32;
}

And let’s see the Help Popup now:

t28_9_method2_help_popup

Pretty nice! Now your documentation has nothing to be jealous of the Xcode default documentation.

Before we move to the next part, open the ViewController.h file, and add the following property declaration (commented of course):

1
2
/*! An application delegate object. */
@property (nonatomic, strong ) AppDelegate *appDelegate;

Along with it, import the AppDelegate class:

1
#import <AppDelegate.h>

The reason we added the above property to the class is to make us able to see later how it is exported using the documentation tools (HeaderDoc and Doxygen), along with the methods we already created.

Files, Classes, Structs and Enums

In the previous part we went through the basic documenting principles that you should be aligned with when writing properties or methods/functions. I intentionally chose to begin demonstrating from that point, as the most of your developing time will be consumed there. Now that we’ve seen some of the essentials of our topic, let’s keep going by taking a look on how to add documentation notes regarding files, classes, structs and enums.

Let’s get started by files, and how you write informative documentation in Objective-C. When sharing programming work with others, or you distribute your code as an open source component, then adding file documentation is almost mandatory, as that’s the best place to provide specific information to your partners or users of your code. Normally, you are going to give extra attention to the header file (.h) and the descriptions in it, as this is the one in the final documentation that will be exported (not in Xcode); however this doesn’t mean that you should not add description to implementation files. Don’t forget that when a project opens in Xcode, everything it’s there, not just the header files, so make sure you don’t leave any part of it undocumented. Besides that, implementation is not shown in exported documentation, but the description of all files is always visible.

Let me introduce you a few new tags that you can use when documenting a file:

  • @file: Use this tag to indicate that you’re documenting a file (header or not). If you’re about to use Doxygen to produce documentation, then you’d better set the file name right after this tag. It’s a top level tag.
  • @header: Similar to the above, but used with HeaderDoc. Don’t use the above if you won’t use Doxygen.
  • @author Use it to write the author info of the file.
  • @copyright: Add copyright info.
  • @version: Use it to write the current version of the file. Pretty important if versioning matters during the project’s lifetime.

There are more tags of course you could use, but those are the most usual ones. I would advice you to go either through the HeaderDoc or the Doxygen documentation, so you can find extra keywords to use if you want so.

Let’s go to add documentation now to the ViewController.h header file. Go to the top of the file, right before the import command. There, add the next lines:

1
2
3
4
5
6
7
8
9
10
11
/*!
 @header ViewController.h

 @brief This is the header file where my super-code is contained.

 This file contains the most importnant method and properties decalaration. It's parted by two methods in total, which can be used to perform temperature conversions.

 @author Your_Name
 @copyright  2015 Your_Name
 @version    15.12.7
 */

You can replace the Your_Name string with your actual name, or your company’s name. Also, it’s always a good idea to use the brief tag instead of just omitting it, as this will enable the documenting systems (you’ll see later in HeaderDoc and Doxygen) to display the short description you add here in the output HTML pages. I remind you once again that instead of the “@” symbol, you can use the backslash, but only for Doxygen. Also, we are not going to see here how the above documentation appears, but we’ll do so a bit later when we’ll produce HTML files.

All the above are great, but the truth is that the default informative comments added by Xcode in each new file you create are pretty good and enough in many cases. You would want to create a file description block when you work with other people in a team and each member must clarify the details of the file(s) he’s in charge for, or when you’re planning to produce complete documentation of the project using HeaderDoc or Doxygen, or lastly, when you’re the sole developer but the project is parted by a big number of files. Anyway, it’s up to you to decide the level of documentation you’re willing to go up to.

Let’s see now how you can document a class or a protocol. Once again, I give you the most usual tags only. Look up in the documentation for more tags.

  • @class: Use it to point the starting point of a documentation block regarding a class. It’s a top level tag, and after it you should provide the class name.
  • @interface: Same as above.
  • @protocol: Just like the above two, just for protocols.
  • @superclass: The superclass of the current class.
  • @classdesign: Use this tag to mention any special design you follow or apply in the current class (for example, you could mention a Singleton class design, or something like this).
  • @coclass: The name of another class that the current one works with.
  • @helps: Name the class which the current one works as a helper for.
  • @helper: Name any other class(es) that work as helpers for the current one.

Actually, you will rarely need any of the above tags, except maybe for the superclass. The list is much longer, but I find it pointless to add more of them here. Let me underline that the tags starting from the superclass and below, are not recognised by Doxygen, only by HeaderDoc. Also, the Quick Help and Help Popup windows in Xcode display the values next to each tag, but not the tags themselves. So, decide if you’re about to use them or not, always depending on whether you’re going to use a documenting system, and which one.

Let’s see an example by documenting our class in the ViewController.h file. Just right before the interface body opening, add these:

1
2
3
4
5
6
7
8
9
10
11
12
13
/*!
 @class ViewController

 @brief The ViewController class

 @discussion    This class was designed and implemented to help people covert temperatures between the Fahrenheit and Celsius scales.

 @superclass SuperClass: UIViewController\n
 @classdesign    No special design is applied here.
 @coclass    AppDelegate
 @helps It helps no other classes.
 @helper    No helper exists for this class.
 */

Now, if you place the caret on the ViewController class name, or you Option+Click on it, you can see how the above description is shown in the Xcode Help.

t28_10_class_name_help_popup

As you see the tags are not displayed, but in this case it doesn’t consist of a problem.

It’s also great that you can see the class short description as you declare objects of it. To really watch this, open the ViewController.m file and go straight ahead in the viewDidLoad method. In there, start typing so you declare a local ViewController object. You’ll see the short description of the file appearing in the code completion popup window:

t28_11_viewcontroller_declare_code_completion

In the same way as above you can document a protocol. Add the next lines before the class in the ViewController.h file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*!
    @protocol ViewControllerDelegate

    @brief The ViewControllerDelegate protocol

    It's a protocol used as a demo here. In a real application it would be quite useful.
 */

@protocol ViewControllerDelegate

/*!
    Nothing to say here... Just testing documentation.
 */

- ( void )thisIsADelegateMethod;

@end

Option+Click on the protocol’s name to see it appearing in the Help Popup window.

t28_12_protocol_help_popup

As you can see above, we also declared a delegate method. You might think at the moment that is meaningless, however I purposely want this method to be there for demo reasons only; when we’ll use HeaderDoc and Doxygen to export documentation later it will be nice to see it in the exported HTML pages.

Now that we’ve talked about files, classes and protocols, and you have hopefully got the big picture, let’s see a couple more special cases: How to document structs and enumerations. Their common element is that you use the @typedef top level tag in both of them, so you indicate the opening of the documentation block (I remind you that using top level tags is absolutely optional).

For Doxygen specifically, you should use the @struct tag for structs, and the @enum tag for enums, instead of the @typedef.

Let’s see the following code struct. Add it to the ViewController.h file right before the opening line of the interface:

1
2
3
4
5
6
typedef struct {
    int sun;
    int clouds;
    int rain;
    int snow;
} WeatherConditionsInDays;

Now add these few lines above it:

1
2
3
4
5
6
7
8
9
10
11
12
13
/*!
 @typedef WeatherConditionsInDays

 @brief  A struct about the weather.

 @discussion
 The values of this structure represent how many sunny, cloudy, rainy, and snowy days existed over the last year. If this was a real app, they could be perfectly used.

 @field sun Good weather
 @field clouds  Where's the sun?
 @field rain    Get an umbrella
 @field snow    Watch out... A snowball is coming!
 */

As you see here, there’s a new tag named @field. This tag is handy to describe each single variable of the struct. Again, I must highlight the difference between the HeaderDoc and Doxygen. In HeaderDoc, this tag is acceptable and valid. However, in Doxygen things change as it’s not compatible with this tag. What we could do in this case is to simply comment each variable separately. Doing that will also display the comment for each one when we’ll access them in the implementation file. Let’s see that (note that the @field tags and the comments above variables contain different values so it’s easier to be identified later):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*!
 @typedef WeatherConditionsInDays

 @brief  A struct about the weather.

 @discussion
 The values of this structure represent how many sunny, cloudy, rainy, and snowy days existed over the last year. If this was a real app, they could be perfectly used.

 @field sun Good weather
 @field clouds  Where's the sun?
 @field rain    Get an umbrella
 @field snow    Watch out... A snowball is coming!
 */

typedef struct {
    /*! Good weather */
    int sun;
    /*! At least it's not raining */
    int clouds;
    /*! Don't forget to get your umbrella */
    int rain;
    /*! Time to go skiiiiiing */
    int snow;
} WeatherConditionsInDays;

If you go now to the ViewController.m file and declare an variable of this struct, then by accessing any of the above values you’ll see the description in the code completion popup window.

t28_13_weather_sun_code_completion

Enumerations are handled in the exact same way, so I leave it to you to as an exercise to create an enum type and document it. Easy task to accomplish, isn’t it? Once your enum is ready, use it in the viewDidLoad method to see if your documentation is appeared in any of the Xcode Help options.

Watching For Errors

As you have seen in all the previous examples, next to the @param tag you must always write the parameter’s name, and after that a proper description. Of course, it’s quite possible that you mistype a parameter name, especially if it’s a bit complex, and to create documentation containing errors. However, there’s a way to be protected against that, and I suspect that you didn’t know that Xcode can be your trusty assistant in that.

Indeed, even though Xcode deals with documentation once its written, it can help you by preventing you mistyping any parameter names. All it gets to do that, is to enable a setting. Let’s see what I mean exactly:

In the Project Navigator, click on the Project’s group, and then go straight ahead to the Build Settings tab, as shown in the next figure:

t28_14_select_build_settings

Once you do so, in the Search box just type the comments keyword and wait to see the results right below. One of the returned results is a setting named Documentation Comments, and (normally) its current value is set to NO. All you have to do is to set the YES value, and you’re ready.

enable documentation

Now, let’s go to see how the above setting affects the way we document our code. Open the ViewController.m file, and go to the private class section, where we are about to declare a private method. Here it is:

1
2
3
4
5
@interface ViewController ( )

- ( float )showCurrentTemperatureInCity : ( NSString * )targetCityName showInScale : ( NSString * )preferredScale;

@end

If we were really going to implement it, this method would return the temperature in the selected city, expressed in the preferred scale (Fahrenheit or Celsius). Now, let’s add a few comments above it:

1
2
3
4
5
6
7
8
9
/*!
    This method returns the current temperature in the selected city, expressed in either Fahrenheit or Celsious degrees.

    @param  targetcityName  The city that the temperature will be returned for.
    @param  preferredScale  Fahrenheit or Celsius.

    @return float   The current temperature of the city.
 */

- ( float )showCurrentTemperatureInCity : ( NSString * )targetCityName showInScale : ( NSString * )preferredScale;

Once you copy-paste the above comments in your Xcode, a warning will appear in the line where the first parameter is documented, telling us that the targetcityName parameter was not found in the function declaration. And guess what? That’s true! Instead of writing the parameter name properly (targetCityName), I wrote it wrongly by not capitalizing the first character of the “city” word (targetcityName). That’s something that in a big project with a lot of comments we would probably not realize, but thankfully Xcode is here to give us a hand and an extra “pair of eyes”.

Now, if you click in the warning triangle icon at the left, you will notice that Xcode auto-suggests the proper parameter name, which you can click so it’s fixed. Alternatively, go and fix it on your own.

fix parameter name

With all the above, you don’t need to be afraid of making any typo while writing parameter names during documentation.

Producing Documentation With HeaderDoc

Now that we have covered the essentials about code documentation, let’s move to another important part, and let’s see how we can create HTML files containing the documentation we added to our project. In this section we are going to use HeaderDoc, a pretty nice tool that works great with the documentation written to files. For your reference, I recommend you visit this site and read more about it. In short, I’m just telling you that using HeaderDoc we’re going to export all the documented parts of the project in HTML pages. In small projects doing that might be meaningless, but in large projects or in cases where you deliver your own SDK to others, an accompanying documentation is almost necessary.

The HeaderDoc tool is actually a command-line tool. It supports various switches to configure the exporting process in a high-detail level, and you can find them in the link I gave you above. Here, we’re going to use just one switch, useful to specify the output directory (the directory where the documentation will reside).

Let’s see some action now. Initially, let’s create a directory for the documentation that will be produced. For easy access, I’m choosing to do that in my Desktop, but you can select any other destination you desire, as long as you update the paths you’ll see later on. So, in my Desktop I created a directory named DocDemo, and in there I added two subdirectories: One named HeaderDoc, and one named Doxygen. As you guess, the documentation produced by each tool will be placed to the respective folder.

t28_17_output_dirs

Next, you must open the Terminal app, so either click on the LaunchPad > Other group > Terminal, or in the Spotlight write the terminal term.

t28_18_spotlight_terminal

Now, it would be a nice idea to navigate yourself in the project directory using terminal, and you can do that easily following the next steps:

  1. In Terminal write the cd command and hit the spacebar. Don’t press the Return key.
  2. In Finder, locate the root directory that contains the project.
  3. Drag and drop this directory straight to the terminal window, as you see in the next screenshot.
t28_19_drag_drop_dir

Then hit the Return key in the keyboard, and to verify that you’re in the right folder just use the pwd command (in terminal always).

The HeaderDoc command we’ll use here is named headerdoc2html, and we’ll form it as follows:

1
headerdoc2html -o OutputDirectory InputDirectory

The OutputDirectory is the directory we created right before, and the input directory is the folder where the project files exist.

Now, let’s use it in real. In your terminal window, write or copy-paste the following part:

1
headerdoc2html -o

Note that after the -o switch there’s a space character.

Next, go in Finder and click on the directory name where the documentation will be exported. Following the steps described above, drag and drop it to the terminal. After that, type the name of the input directory followed by a slash. Here’s how the whole command should look like:

1
headerdoc2html -o /Users /gabriel /Desktop /DocDemo /HeaderDoc DocDemoObjC /
t28_20_terminal_final

You will see various stuff appearing, but no need to pay special attention to that right now. Once it gets finished, mark and copy the path of the output directory, write the next command in terminal:

1
gatherheaderdoc

and paste the path. Press Return and let it run. This command will create a table of contents page, where all commented files, classes and methods will exist in one place.

That’s it. Now go to Finder, and open the masterTOC.html file in your browser. Here’s what you’ll see:

t28_21_toc

If you click in the ViewController link, here’s the page that you’ll be guided to:

t28_22_view_controller_page

There you can find the description of the file, and the class, the protocol and the struct with links to them along with their brief descriptions. The struct details are shown in the same page.

t28_23_struct_doc_page

Notice that the fields contain double values, but that’s only because we added comments both using the @field tag, and above each struct variable. If you want, you can go back in Xcode and delete any of the two. Next, run again the HeaderDoc commands in terminal and get back here.

If you click in the class link, you’ll go to a new page, where you can see its description, the two methods and the one property we declared in the header file.

t28_24_class_page

Now that you’ve seen the results, walk freely around everywhere in the documentation pages and see how everything is being displayed. HeaderDoc usage doesn’t stop here, but that’s what you’ll need in most of the cases.

Producing Documentation with Doxygen

Time to leave HeaderDoc behind us and let’s see how to use a quite widespread documenting system, named Doxygen. Before we see the details concerning it, I should say that Doxygen was not originally designed to parse documentation in Objective-C. However, it is going to perfectly work as it aims to C and C++ style languages mostly, and as you’ll see by yourself, it supports a variety of languages. Besides that, it contains a large amount of documenting tags, and if you decide to write documentation that will eventually be parsed by Doxygen, you can use any of them so as to have greater compatibility.

Doxygen is a third-party application which you must download before use it. There are versions of it for all common operating systems, so it can work for you even if you’re not developing for iOS only. At this point, let me give you three important links:

  1. In this link you can find all the resources you need regarding the code documentation.
  2. Here you can find all the tags supported by Doxygen, and by clicking to each one you get extra information about its usage.
  3. Lastly, you can visit this page to download the Doxygen application.

Before we download it, let me note that you can find much more than what I just mentioned above in the Doxygen website. Actually, as you can see in the next screenshot, there’s a menu panel at the left side, which you can use to dive in various parts of it and find numerous details and how-tos.

doxygen menu

Now, pay a visit to the last link I gave you above, and scroll a bit down to the page until you find an area named A binary distribution for Mac OS X 10.5 and later. Click either in the ftp, or in the http link to initiate the package downloading. Depending on your Internet connection speed, it might take a few seconds for the download to complete, as the file is about 55 Mb.

Once the download process is over, open the package. Then, get the Doxygen application and drag it to your Applications directory.

If you don’t want to add it to the Applications directory it’s okay. Just place it anywhere else you want. After all, Doxygen is a fully self-contained application, so to remove it just delete its app file, no matter where you’ll place it.

Assuming now that you’ve copied it in the Applications directory, click in the Launchpad to find it easily. Click it to let it run.

NOTE: If you get a message saying that the application cannot be opened because it’s from an unidentified developer, follow the next steps to overcome it: In Finder, open the Applications directory. Locate the Doxygen app, and then Ctrl+Click it. Select the Open option in the context menu, and in the new dialog window that will be shown, click to the Open button.

Now, leave the Doxygen app aside, and go back to Xcode. We’ll perform two changes in two tags, so everything to be recognised. Make sure to open the ViewController.h file, and in its description block replace the @header top level tag with the @file tag. Also, a modification is needed to the documentation block of the struct, where the @typedef tag must be replaced with the @struct tag. After having done these, let’s leave Xcode again.

If you’ve used Doxygen in the past, then you definitely know what to do. However, I’ll assume it’s your first time in this app, so let me present you the most important steps.

Right next it’s the initial Doxygen window upon first run:

doxygen

Before I tell you the exact settings you should apply, it’s necessary to say that Doxygen provides two modes of usage: The Wizard which consists of a simple and general way, and the Expert mode, where a huge number of settings can be specified so you customize each detail of the produced documentation.

I’m not going to focus on the Expert mode, because the applied settings there are highly depending on the personal needs of each developer. That means that we’ll stick with the Wizard mode, but prior to this, I think that it worths to take a super-fast walk in the Expert mode. By clicking in the Expert button in the main window area, you instantly see that you are given with a great number of settings in the main panel. You can scroll up and down to go trough all of them, but they’re not just them. At the left side, there’s a smaller panel titled Topics, and by clicking to another topic you access its own settings. If you have the time, visit all of them. You might find useful options that you would like to use in your apps.

Now, let’s focus in the Wizard mode. Make sure to click on the respective button, so you can follow what I describe next. At first, at the top of the window we must specify where Doxygen runs from. Just click in the Select button, and select the Applications directory in your computer, or any other location where you’ve copied the Doxygen app into.

Next, let’s specify the project’s name. In the Project Name: field, set the DocDemo in Objective-C value (or anything else you desire). If you want, also fill the next fields in too. Below that, we must specify the path to our project. Once again, use the Select button and navigate yourself to the root directory of the project. It would be a good idea to click in the Scan recursively, so Doxygen can scan subdirectories too.

Lastly, specify where the produced documentation should be stored. If you remember, we had created the Doxygen subdirectory in the DocDemo directory in Desktop for this purpose. So, click on the Select button next to the Destination Directory field, and pick it.

t28_31_doxygen_project_settings

Next, in the Topics list at the left, click on the Mode option. In the new settings, click in the All Entities option:

t28_32_document_mode_settings

Next, again in the Topics list, click on the Output option. Here you can find various exporting options. Feel free to select any kind of output you desire. For this example, I deselected the LaTeX option, I just left the HTML on.

t28_33_doxygen_output_settings

Finally, in the Diagrams options you can just leave the default setting as they are.

It’s time now to produce the documentation. Please, be sure that you’ve set all the options mentioned above before you continue. You did it? Okay, let’s keep going. Click on the Run button (next to the Wizard and Expert buttons), and in the main window area now you will see a new button titled Run doxygen. Click it to let the app start creating the HTML files for you. In the white area you’ll see some output messages, and if something is wrong, that’s the place where you’ll see it.

Anyway, once it’s finished, open Finder and navigate straight ahead to the output directory to see the exported files. You will notice that a bunch of files have been created, and the one you’re looking for is named index.html. Double click it to open it in the browser. Alternatively, if you don’t care to see the exported files, simply click on the Show HTML output in the Doxygen window.

This is the first screen you face by opening the index page:

t28_34_doc_index_page

It just contains the project title we set earlier, the generation timestamp, and a couple of links at the top. Use these links to navigate yourself around. For example, if you click on the Classes link, you’ll get a list of all classes existing in the project. The interesting part here is that next to each class they are displayed the brief descriptions we wrote (only where we wrote them).

t28_35_doc_classes

Here’s what you see when tapping in the ViewController class:

t28_36_doc_viewcontroller_class

As you can see, the detailed documentation of the methods and the one public property we have in the project can be found there. Another interesting point is under the Files menu, where all the parsed files are listed, and by selecting the ViewController.h file. In there you find the file description, and everything we declared: The class, the protocol and the struct.

t28_37_doc_file_viewcontroller

Use the More… links to go to the details of any of the above. There’s also a link titled ”Go to the source code of this file.”, which if it’s tapped, it displays the code of the ViewController.h header file. Note that whatever is written in header files is public, so it can be displayed here. However, don’t expect to find any implementation code at all. That’s for “your eyes only”.

t28_38_doc_file_code

So, I’m pretty sure at this point that you’ve got the grasp of all the above. Navigate in the exported HTML pages, go back in Xcode to make changes in documentation, and re-produce everything. Also, don’t hesitate to set advanced settings and see what happens. In general, play around as much as you want, and familiarize yourself with Doxygen. It’s a great tool that can be used for both small and big projects.

Creating a Demo App in Swift

Let’s turn page now for one more time, and let’s say a few words about documenting your code in Swift. To make things as much clear as possible, let’s create a new demo project, this time in Swift.

So, begin creating one in Xcode, and in the first step of the guide specify the Single View Application as the template of the application. Next, name the project DocDemoSwift, and also be sure that the selected language is the Swift. Proceed, select a directory to save the project, and let Xcode to create it.

Documenting in Swift

Code documentation in Swift is less powerful that in Objective-C, and that’s the reason I left the discussion about it for the end. Unfortunately, neither HeaderDoc nor Doxygen support Swift (at least for now, I can’t say what may happen in the future), and the documentation formatting is now based in the reStructuredText, an open source project for which you can find more info here.

From all the tags we met in the previous parts of this tutorial, there are only two that can be used in this case: The param and return, which actually becomes returns (note the “s” at the end). Also, neither the @ or the backslash symbol is supported. Instead, both of these tags are included in semicolons, for example :param:. After that, the parameter name must be written, followed by its description.

The brief and discussion tags are not used, but the respective parts can be added to the documentation as the tags are inferred, meaning that a short text at the beginning of the documentation block is considered to be the brief description, and bigger text parts after that are the discussion.

The new and interesting thing here is that in the discussion part you can add ordered and unordered lists, as well as fields with descriptions. For example, to add an ordered list you just need to write:

1
2
3
1. First item
2. Second item
3. Third item

For unordered lists, you either use the asterisk (*), or the dash (-) symbol. For example:

1
2
3
* An item
* Another item
* More items

And:

1
2
3
- An item
- Another item
- More items

Note: If you are familiar with the Markdown syntax, then the above are already known to you.

To have fields in the discussion area, you just have to write the field name surrounded by semicolons, and then the description:

1
:MyField : This is a field example

All the above, including the two tags (param and returns) are enough so you write proper documentation. Even though not as many options as in Objective-C are provided, I believe that all the previous stuff is all you need, so I’ll show you no more.

Let’s go to Xcode now to see an example of all those. Open the ViewController.swift file, and in there define the following method (similar to the Objective-C example):

1
2
3
func toCelsius (fromFahrenheit : Float ) -&gt; Float {
    return (fromFahrenheit - 32 ) / 1.8;
}

Having in mind the prior description about the documentation in Swift code, here’s how the same comments we added in Objective-C version are written here:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
It converts temperature degrees from Fahrenheit to Celsius scale.

This method accepts a float value representing the temperature in Fahrenheit scale and it converts it to the Celsius scale.
To use it, simply call toCelsius(50) or self.toCelsius(50)

:param: fromFahrenheit The input value representing the degrees in the Fahrenheit scale.

:returns:   float The degrees in the Celsius scale.
*/

func toCelsius (fromFahrenheit : Float ) -&gt; Float {
    return (fromFahrenheit - 32 ) / 1.8;
}

Note that we use the /** – */ notation here. By looking in the Help popup, here’s the result:

t28_40_func_help_popup_swift

Also, if you start typing the method’s name in the viewDidLoad method, the brief description is appeared in the code completion:

t28_41_func_code_completion_swift

Now, let’s create a super-simple new method that will do nothing at all:

1
2
3
func myHelloMethod ( ) {
    println ( "Hello there" )
}

We are going to document the above method by creating lists and fields. What you’ll see next is clearly an example, so don’t try to find any logic in the comments.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
    This method was implemented to do nothing hard, just to say hello.

    Here is a demo of an ordered list:

    1. One
    2. Two
    3. Three
    4. Four

    How about an unordered list?

    * North
    * East
    * South
    * West

    Let's add a couple of fields now:

    :Job: My dreaming job
    :Salary:    My dreaming salary

*/

func myHelloMethod ( ) {
    println ( "Hello there" )
}

By Option+Click in the method’s name, here’s what is being displayed in the Help popup:

t28_42_hello_method_help_popup

All the above is pretty much what you need to document your code in Swift. However, don’t hesitate to try more options after having read the reStructuredText manual (or some of it… it’s huge).

Summary

In this tutorial we’ve managed to see many aspects concerning the code documentation. We talked for both Objective-C and Swift, and went through the most important principles regarding each one. As you found out, in Objective-C you have a ton more options to use, but yet, the provided tools are just fine in Swift as well. What I presented today is not what only exists. There are more you can find and use, but my point was to introduce you the most usual documenting information. What you’ve read here, is what you’ll need in nine out of ten cases. Also, don’t forget the two interesting tools we met, HeaderDoc and Doxygen. Both of them can produce great documentation, and they can become nice “friends” of yours. As a last word, I’d like to highlight once again that documenting your code is really a big deal. You may often doubt about that, but trust me, it worths each second you’ll consume for this task. Help both yourself and others by writing proper documentation, straight into the point, that explains everything you do in your code. If you’re not used to doing that, you’d better start now, even if you’re not a young developer. See you!

Source : appcoda[dot]com
post from sitemap

Không có nhận xét nào:

Đăng nhận xét