Documenter le code swift pour Xcode

La documentation est très importante, on le sait. Et une bonne documentation passe aussi par les commentaires du code de votre application.

Je vous avais même dit qu'il était possible de bien intégrer ses commentaires à son IDE pour qu'il les comprenne, les prenne en compte et les utilise en documentation.

Pour Swift et Xcode, suivez le guide.

Les commentaires

protocol Vehicule {
    var distance: Double { get }
    
    func roule()
}

Partons de ce code, joyeusement écrit à l'arrache. C'est donc un protocole qui décrit les véhicules en général. Selon ce protocole ils doivent tous rouler et on doit toujours pouvoir récupérer leurs distances.

Leurs distances ? Récupérer la distance d'un véhicule ne veut pas dire grand chose. Le développeur de ce protocole sait sûrement de quoi il veut parler mais pas le premier venu, d'où l'intérêt des commentaires ici.

protocol Vehicule {
    // Distance parcourue par le vehicule
    var distance: Double { get }
    
    // Commande faisant rouler le vehicule
    func roule()
}

Xcode et les commentaires

Ce que l'on va faire est simple. Lorsque l'on fait alt + clic sur une entité de notre code (classe, protocole, variable, etc.), Xcode ouvre une popup avec une documentation de cette entité. On veut remplir cette popup.

La description

Pour cela il faut ajouter des commentaires d'une autre forme au-dessus de notre attribut distance et de notre méthode roule().

protocol Vehicule {
    /**
     Distance parcourue par le vehicule
     
     */
    var distance: Double { get }
    
    /**
     Fait rouler le vehicule
     
     */
    func roule()
}

Ceci va ajouter nos commentaires en description de chaque entité.

La description supporte le Markdown. Vous pourrez donc styliser votre description avec du gras, de l'italique, des listes, etc.

protocol Vehicule {
    /**
     Distance parcourue **par** le vehicule.
     
     - 1...
     - 2...
     
     */
    var distance: Double { get }
    
    /**
     Fait rouler le vehicule
     
     ```
     voiture.roule()
     ```
     
     */
    func roule()
}

Comme vous le voyez pour la méthode roule(), il est possible d'afficher un bloc de code. C'est utile si vous souhaitez donner un exemple d'utilisation.

Les paramètres

Il est aussi possible d'indiquer une définition pour chaque élément de la liste d'arguments. Il faut utiliser le marqueur Parameter

Par exemple :

protocol Vehicule {
    /**
     Distance parcourue **par** le vehicule.
     
     - 1...
     - 2...
     
     */
    var distance: Double { get }
    
    /**
     Fait rouler le vehicule
     
     ```
     voiture.roule(220.0)
     ```

     - Parameter vitesse: vitesse à laquelle doit rouler le vehicule
     */
    func roule(vitesse: Double)
}

Ajouter un élément à la liste en suivant le même template pour ajouter la description d'un nouvel argument.

protocol Vehicule {
    /**
     Distance parcourue **par** le vehicule.
     
     - 1...
     - 2...
     
     */
    var distance: Double { get }
    
    /**
     Fait rouler le vehicule
     
     ```
     voiture.roule(220.0, "nord")
     ```

     - Parameters:
         - vitesse: vitesse à laquelle doit rouler le vehicule
         - direction: direction dans laquelle doit aller le vehicule
     */
    func roule(vitesse: Double, direction: String)
}

Lorsque vous avez beaucoup de paramètres, vous pouvez réduire la verbosité de votre commentaire en utilisant le marqueur Parameters.

Le retour et les erreurs

Si votre fonction retourne autre chose que void ou si elle peut lever une erreur, il peut être utile de le préciser.

protocol Vehicule {
    /**
     Distance parcourue **par** le vehicule.
     
     - 1...
     - 2...
   
     */
    var distance: Double { get }
    
    /**
     Fait rouler le vehicule
     
     ```
     voiture.roule(220.0, "nord")
     ```
     
     - Parameters:
         - vitesse: vitesse à laquelle doit rouler le vehicule.
         - direction: direction dans laquelle doit aller le vehicule.
     
     - Throws: Lève une erreur s'il est impossible d'avancer à cause de la vitesse ou
     si la vitesse dépasse le maximum authorisé.
     Erreurs possibles :
         - `VehiculeError.VitesseNulle`
         - `VehiculeError.VitesseLimite`

     - Returns: `true` si la distance parcourue est un nouveau record.
     */
    func roule(vitesse: Double, direction: String) throws -> Bool
}

Le Markdown est bien-sûr autorisé pour l'écriture du texte de ces marqueurs.

Les messages et les informations

Autres fonctionnalités : ce que j'appelle les "messages".

protocol Vehicule {
    /**
     Distance parcourue **par** le vehicule.
     
     - 1...
     - 2...
     
     Fin.
     
     - Warning: Propritété en lecture seule.
     - Important: La distance est exprimée en metres.
     */
    var distance: Double { get }
    
    /**
     Fait rouler le vehicule
     
     ```
     voiture.roule(220.0, "nord")
     ```
     
     - Parameters:
         - vitesse: vitesse à laquelle doit rouler le vehicule.
         - direction: direction dans laquelle doit aller le vehicule.
    
     - Throws: Lève une erreur s'il est impossible d'avancer à cause de la vitesse ou
     si la vitesse dépasse le maximum authorisé.
     Erreurs possibles :
         - `VehiculeError.VitesseNulle`
         - `VehiculeError.VitesseLimite`
     
     - Returns: `true` si la distance parcourue est un nouveau record.
     */
    func roule(vitesse: Double, direction: String) throws -> Bool
}

Il s'agit en fait d'ajouter à notre documentation, des messages de warning, de remarque, etc.

On peut aussi indiquer des informations générales comme l'auteur et la version :

protocol Vehicule {
    /**
     Distance parcourue **par** le vehicule.
     
     - 1...
     - 2...
     
     Fin.
     
     - Authors:
        - MindsersIT <un@test.com>
        - Mindsers <deux@test.com>
     
     - Warning: Propritété en lecture seule.
     - Important: La distance est exprimée en metres.
     */
    var distance: Double { get }
    
    /**
     Fait rouler le vehicule
     
     ```
     voiture.roule(220.0, "nord")
     ```
     
     - Parameters:
         - vitesse: vitesse à laquelle doit rouler le vehicule.
         - direction: direction dans laquelle doit aller le vehicule.
    
     - Throws: Lève une erreur s'il est impossible d'avancer à cause de la vitesse ou
     si la vitesse dépasse le maximum authorisé.
     Erreurs possible :
         - `VehiculeError.VitesseNulle`
         - `VehiculeError.VitesseLimite`
     
     - Returns: `true` si la distance parcourue est un nouveau record.
     - Version: 1.4
     */
    func roule(vitesse: Double, direction: String) throws -> Bool
}

A force d'information on se retrouve avec beaucoup de commentaires, mais c'est pour la bonne cause !

N'hésitez pas à chercher dans la documentation d'Apple sur le sujet. Il y a bien plus de marqueurs que ceux que je vous ai présenté.

En faire plus avec ses commentaires

Utiliser ce système de documentation est une vraie plus-value pour votre projet. Ces informations vous sont utiles en tant que développeur du projet, mais aussi à tous les développeurs susceptibles de travailler avec votre projet.

D'ailleurs ce sont des informations que l'on retrouve aussi dans les documentations d'API que l'on peut rendre disponible sur le site d'une library. Pourquoi réécrire la documentation deux fois ?

Des outils tel que jazzy peuvent scanner votre code pour en extraire les commentaires de documentation et construire à partir de ça une documentation en HTML ; à l'instar de ce qui se fait déjà du côté de jsdoc, javadoc ou encore phpdoc.