Règles SwiftLint personnalisées

Salut Habr! Je m'appelle Alex, je suis développeur iOS chez FINCH. Bientôt, le Nouvel An est le moment de commencer à vivre différemment, et une chose aussi cool que SwiftLint aidera à cela. Dans l'article, je vais vous expliquer pourquoi il doit être implémenté dans tous les projets, y compris les projets hérités et les animaux de compagnie, et montrer également comment tirer le meilleur parti de cet outil en utilisant des lignes régulières.

Je ne vous dirai pas ce qu'est SwiftLint et comment l'installer - si vous n'êtes pas familier avec l'outil, alors il vaut mieux lire la documentation officielle .

Il est préférable de passer au problème commun qui se pose lorsque vous travaillez avec de grands projets - la non-conformité avec les guides de style sous le couvert de correctifs ou d'autres choses. Mais en fait, même si vous lisez les guides de style et que vous pouvez même les appeler dans un état d'intoxication extrême, personne ne garantit qu'une faute de frappe banale ne peut pas se produire, ce qui, bien qu'il n'entraîne pas une rupture de logique, mais qui affectera clairement le plaisir esthétique.

Alors, souvenez-vous:

1. SwiftLint vous permet de faire:

  • Un style avec des guides de style

En fait, tout.

L'article pourrait se terminer ici, mais s'il en était ainsi, je ne commencerais pas du tout à écrire cet article. Fait intéressant, SwiftLint ne vous permet pas de faire - écrire le code des correctifs à chaud.

2. SwiftLint vous permet d'empêcher:

  • Forcer le déballage
  • Délégués forts
  • CyclomaticComplexity
  • Quelque chose d'autre ...

Je pense que c'est bien d'être à l'abri de telles erreurs, non? C'est particulièrement bon pour un développeur novice, car il n'apprend et parfois ne soupçonne pas de telles erreurs.

3. Swiftlint peut être développé selon ses propres règles.

Je commencerai par spécifier la finale pour les classes qui ne seront pas parentes aux autres. Grâce au final, nous économisons du temps de montage du projet. Voici ce que la documentation Apple nous dit sur les classes finales:
Les déclarations avec accès interne (par défaut si rien n'est déclaré) ne sont visibles que dans le module où elles sont déclarées. Étant donné que Swift compile normalement les fichiers qui composent un module séparément, le compilateur ne peut pas déterminer si une déclaration interne est remplacée ou non dans un autre fichier. Cependant, si l'optimisation du module entier est activée, tout le module est compilé ensemble en même temps. Cela permet au compilateur de faire des inférences sur l'ensemble du module ensemble et de déduire les déclarations finales avec des déclarations internes s'il n'y a pas de remplacements visibles.

Nous résoudrons cette inattention par une simple saison régulière. Ensuite, j'écrirai immédiatement sur ruby ​​afin que vous puissiez intégrer du code directement dans votre projet:

final_class: included: ".*.swift" name: "Final class requrement" regex: '^class' message: "All classes must be final or nonfinal" saverity: error 

Un petit exemple assez simple. Je n'écrirai pas quelque chose de similaire pour chaque règle, mais le code source sera à la fin de l'article.

 class SomeClass { } //  internal class SomeClass { } //  /* @non-final */ class SomeClass { } //   

Le point suivant est requis init. Nous, dans l'entreprise, n'utilisons pas de storyboards, il n'est donc pas tout à fait normal de spécifier un initialiseur fatal dans chaque classe UIView. Pour ce cas, nous avons notre propre NLView (NL - NibLess) - une classe dans laquelle init requis n'est implémenté qu'une seule fois. Les nouveaux développeurs du projet ne le savent peut-être pas, mais les avantages de SwiftLint grondent toujours au lieu d'un responsable. Ou avec.

 required_init: regex: 'required init\?\(coder: NSCoder\)' message: "Use NL class instead" 

Si vous utilisez toujours des storyboards, vous pouvez utiliser les règles suivantes pour savoir que tous vos storyboards sont privés:

 open_iboutlets: included: ".*.swift" name: "IBOutlet opening" regex: '@IBOutlet ?(weak){0,1} var' message: "IBOutlet should be private" severity: error 

 open_ibaction: included: ".*.swift" name: "IBAction opening" regex: '@IBAction func' message: "IBAction should be private" severity: error 

Il arrive souvent que Foundation soit utilisé là où il est complètement inutile. Il est donc préférable de le mettre en valeur à chaque fois pour ne pas oublier:

  foundation_using: included: ".*.swift" regex: 'import Foundation' message: "Do you really need for Foundation ???" 

J'espère que tout le monde sait que l'impression est une opération assez difficile, qui peut considérablement nuire aux performances des applications (en particulier dans les boucles). Le seul verdict - les impressions ne devraient pas être du tout.

 print_using: regex: 'print' message: "Print decrease performance of the app" severity: error 

En outre, vous ne devez pas créer de protocoles de classe uniquement, car il est possible qu'une telle syntaxe devienne rapidement obsolète et ce n'est pas recommandé par les développeurs Swift .

 class_protocol: regex: ': class' message: "Use Anyobject instead" 

Voici la règle pour les projets qui utilisent R.swift.

 image_name_initialization: included: ".*.swift" name: "Image initialization without R.swift" regex: 'UIImage\(named:[^)]+\)' message: "Use R.image.name() or typealias of this instead" severity: error 

Ce n'est qu'une petite partie de ce que j'ai pu trouver, mais il y a encore moins d'exemples sur Internet. Vous pouvez regarder toute ma «collection» sur github .

Merci de votre attention. Si vous utilisez également SwiftLint avec des règles personnalisées, parlez-nous-en - je serai heureux de discuter des cas possibles.

Source: https://habr.com/ru/post/fr481666/


All Articles