Utilisation de SwiftLint Static Code Analyzer dans les applications bancaires mobiles iOS

Oleg Ivanov, responsable du centre de compétences pour les chaînes de services à distance



Bonjour à tous! Comme promis dans l'article «Mobile Banking de l'ICD: historique du développement» , je souhaite aujourd'hui parler des analyseurs de code statique et de l'expérience de leur application dans les applications mobiles iOS de la banque.

Fixons l'objectif que nous voulons atteindre en utilisant cette boîte à outils:

  • détection précoce des erreurs et des lacunes;
  • Code Style ( — , ).

Une façon courante d'atteindre nos objectifs consiste à vérifier manuellement le code - Revue de code .

Le testeur ou un groupe de testeurs examine attentivement le code testé, puis il identifie les erreurs ou les sections du code qui pourraient devenir erronées à l'avenir, et donne des recommandations pour l'améliorer par des commentaires sur le code, qui après un certain temps (!) Sera analysé et corrigé par le développeur. Comme nous pouvons le voir, un processus de vérification de code long et coûteux émerge. De plus, il y a toujours un facteur humain - certaines erreurs peuvent simplement être ignorées par les réviseurs.

Ici, les analyseurs de code statique viennent à notre aide.

Analyseurs de code statique- lancer un processus automatisé pour détecter les erreurs et les défauts dans le code source des programmes.

Les analyseurs de code statique ne sont pas une panacée ni un remplacement pour la révision manuelle du code, mais ils sont un excellent outil qui vous permet de réduire le temps consacré à la vérification et de trouver rapidement des erreurs structurées. La pertinence d'utiliser des analyseurs statiques ne fera qu'augmenter avec le temps.

En tant qu'analyseur de code statique dans nos projets iOS, nous utilisons SwiftLint.

SwiftLint est un utilitaire de vérification automatique du code Swift qui s'exécute pendant la phase de construction d'un projet. L'utilitaire contient un ensemble de règles avec la possibilité de compléter cet ensemble avec vos règles personnalisées. L'outil est également utilisé pour se conformer au style de code.

Pourquoi est-il important de suivre le style de code dans l'application?
Lorsque vous êtes un développeur sur un projet, tout est simple: vous écrivez dans votre propre style et vous pouvez vous permettre le code de cette façon:



Mais lorsque vous travaillez dans une grande équipe de développement. un facteur important est la vitesse de compréhension et de recherche de la place pour insérer des améliorations dans le code de quelqu'un d'autre.
Et ici, tous les membres de l'équipe doivent accepter les conventions et les règles pour écrire du code. Mais comment vérifier leur conformité? Encore une fois, l'analyseur de code statique SwiftLint nous aidera. Et notre code aura un aspect agréable que tous les membres de l'équipe comprendront:



Pour vous familiariser avec l'outil, je vous recommande de lire la documentation officielle .

L'installation de SwiftLint est simple:

  1. Ajouter le pod 'SwiftLint' au podfile du projet
  2. Ajoutez une nouvelle «Exécuter la phase de script» au projet.

    "${PODS_ROOT}/SwiftLint/swiftlint"
  3. SwiftLint .swiftlint.yml
  4. .swiftlint.yml , SwiftLint

Si le projet d'intégration SwiftLint contenait déjà du code, vous devrez être patient et corriger systématiquement toutes les recommandations SwiftLint. Il les forme à travers les affichages d'erreur et d'avertissement habituels avec des conseils complets sur les recommandations.



Toujours entre parenthèses, il affiche le nom de la règle qui a initié la recommandation (operator_usage_whitespace) .

Dans ce cas, ce sont les suivantes:

Utilisation des
opérateurs Espaces Les opérateurs doivent être entourés d'un seul espace.

Code correct: Code




recommandé:



Chaque règle possède un ensemble d'attributs:

Identifiant : operator_usage_whitespace
Activé par défaut : désactivé
Prend en charge la correction automatique :oui
Type : style
Règle Analyzer : non
Version minimale du compilateur Swift : 3.0.0
Configuration par défaut : avertissement

Faites attention à la «version minimale du compilateur Swift» - corrélez l'utilisation des règles avec cet attribut et avec les paramètres de votre projet.

La « configuration par défaut » attribut montre comment les règles avec cet attribut seront perçus: soit un avertissement régulier, ou une erreur de compilation, comme une fonte force règle (configuration par défaut: erreur)

Toutes les règles se trouvent dans un très pratique et illustré documentation.

Ci-dessous je vais vous présenter les règles que nous avons choisies dans notre équipe, vous pouvez les utiliser comme exemple pour créer votre projet.

Nous avons divisé toutes les règles en fonctionnelles et stylistiques - oui, oui, oui, et un espace à l'intérieur de chaque accolade, et les paramètres de fermeture devraient être sur la même ligne que le crochet d'ouverture, et ... :). Je ne peins pas les règles, vous pouvez facilement trouver des informations à leur sujet en utilisant le lien ci-dessus.

Fonctionnelle :

- private_outlet
- force_unwrapping
- force_cast
- force_try
- strong_iboutlet
- private_action
- block_based_kvo
- contains_over_first_not_nil
- discarded_notification_center_observer
- discouraged_direct_init
- discouraged_object_literal
- discouraged_optional_boolean
- discouraged_optional_collection
- duplicate_imports
- dynamic_inline
- empty_count
- empty_parameters
- empty_parentheses_with_trailing_closure
- EMPTY_STRING
- explicit_enum_raw_value
- function_default_parameter_at_end
- generic_type_name
- identical_operands
- implicit_getter
- is_disjoint
- notification_center_detachment
- nsobject_prefer_isequal
- redundant_set_access_control
- unused_capture_list

Le style de :

- unneeded_parentheses_in_closure_argument
- let_var_whitespace
- yoda_condition
- colon
- virgule
- closure_parameter_position
- closure_spacing
- collection_alignment
- leading_whitespace
- marque
- opening_brace
- operator_usage_whitespace
- operator_whitespace
- protocol_property_accessors_order
- return_arrow_whitespace
- switch_case_alignment
- statement_position
- trailing_comma
- trailing_newline
- unneeded_break_in_switch
- custom_rules
- closure_end_indentation
- file_name_no_space
- unowned_variable_capture
- no_space_in_method_call
- contains_over_filter_count
- contains_over_filter_is_empty
- contains_over_range_nil_comparison
- duplicate_enum_cases
- empty_collection_literal

également un objectif de la SwiftLint nous avons choisi seul le catalogue avec notre base de code en ajoutant les paramètres appropriés dans le fichier de configuration .swiftlint.yml:

inclus:

- <répertoire de base de code>


Nous avons créé une règle d'interdiction de territoire fonctions d'impression. l'impression est une opération assez difficile. Via le fichier de configuration .swiftlint.yml:

custom_rules:
  disable_print:
    included: ".*\\.swift"
    name: "print usage"
    regex: "((\\bprint)|(Swift\\.print))\\s*\\("
    message: "Prefer os_log over print"
    severity: error

Cette règle nous a incités à écrire notre fonction de journalisation (avec un niveau de journalisation). Cette journalisation est utilisée par les développeurs pour un débogage rapide, par exemple, des journaux avec des paramètres, un corps de demande / réponse sont nécessaires pour toute analyse d'erreurs, pour le développement. Pour la version, le niveau de journalisation dans notre version .none. Le reste de l'utilisation de la fonction d'impression entraînera une erreur de génération de projet.

func logApp(level: Constants.LogLevel, items: Any...) {
    if Constants.logLevel == .none {
        return
    }
    
    if level.rawValue <= Constants.logLevel.rawValue {
        // swiftlint:disable disable_print
        if let strings = items as? [String] {
            for string in strings {
                print(string)
            }
        } else {
            print(items)
        }
        // swiftlunt:enable disable_print
    }

Mais pour utiliser la fonction d'impression, nous avons dû fermer son appel dans notre fonction de journalisation en utilisant SwiftLint pour ignorer nos propres règles sur un bloc de code marqué avec une instruction spéciale.

// swiftlint:disable disable_print
// swiftlunt:enable disable_print

SwiftLint a la capacité d'ignorer ses propres règles:

// swiftlint:disable <rule1 [rule2 rule3…]>
<,   SwiftLint   rule1 [rule2 rule3…]>
// swiftlunt:enable <rule1 [rule2 rule3…]>

Ou

// swiftlint:disable all
<,   SwiftLint   >
// swiftlint:enable all

Profitez de cette opportunité, pleinement consciente qu'elle est nécessaire!

En conclusion, je note : l'utilisation de SwiftLint dans notre équipe a réduit le coût de la révision manuelle du Code de 20%. Maintenant, nos réviseurs ne font pas attention aux erreurs typiques (Force Cast, etc.), au style de code et peuvent se concentrer entièrement sur la vérification du nouveau code. Ce qui a considérablement augmenté l'efficacité globale de l'équipe (pas besoin de corriger de telles erreurs de vérification, ce sont des employés qualifiés, dont le temps est très important).

Tout! Maintenant, SwiftLint est toujours avec vous :)


All Articles