Regras personalizadas do SwiftLint

Oi Habr! Meu nome é Alex, sou desenvolvedor iOS no FINCH. Em breve o Ano Novo será o momento de começar a viver de maneira diferente, e uma coisa interessante como o SwiftLint ajudará nisso. No artigo, explicarei por que ele deve ser implementado em todos os projetos, incluindo projetos herdados e de estimação, e também mostrarei como tirar o máximo proveito desta ferramenta usando linhas regulares.

Não vou lhe dizer o que é o SwiftLint e como ele pode ser instalado - se você não estiver familiarizado com a ferramenta, é melhor ler a documentação oficial .

É melhor ir direto ao problema comum que surge ao trabalhar com grandes projetos - não conformidade com guias de estilo sob o pretexto de hotfixes ou outras coisas. Mas, de fato, mesmo que você leia os guias de estilo e possa chamá-los em um estado de extrema intoxicação, ninguém garante que um erro de digitação banal não possa ocorrer, o que, embora não implique uma quebra na lógica, mas que claramente afetará o prazer estético.

Então lembre-se:

1. SwiftLint permite que você faça:

  • Um estilo com guias de estilo

Na verdade tudo.

O artigo poderia terminar aqui, mas, se assim fosse, eu não começaria a escrever este artigo. Curiosamente, o SwiftLint não permite que você faça - escreva o código ... hot fixes.

2. SwiftLint permite impedir:

  • Forçar desembrulhar
  • Delegados fortes
  • CyclomaticComplexity
  • Outra coisa ...

Eu acho que é bom estar seguro de tais erros, certo? Isso é especialmente bom para um desenvolvedor iniciante, pois ele apenas aprende e às vezes não suspeita de tais erros.

3. O Swiftlint pode ser expandido de acordo com suas próprias regras.

Começarei especificando final para as turmas que não serão pais de outras pessoas. Graças à final, economizamos tempo de montagem do projeto. Aqui está o que a documentação da Apple nos diz sobre as aulas finais:
Declarações com acesso interno (o padrão se nada for declarado) são visíveis apenas no módulo em que são declaradas. Como o Swift normalmente compila os arquivos que compõem um módulo separadamente, o compilador não pode determinar se uma declaração interna foi ou não substituída em um arquivo diferente. No entanto, se a Otimização do módulo inteiro estiver ativada, todo o módulo será compilado ao mesmo tempo. Isso permite que o compilador faça inferências sobre todo o módulo e conclua as declarações com declarações internas se não houver substituições visíveis.

Resolveremos essa desatenção em uma estação regular simples. Em seguida, escreverei imediatamente para o ruby, para que você possa incorporar o código diretamente no seu projeto:

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

Um exemplo pequeno e bastante simples. Não escreverei algo semelhante para cada regra, mas o código-fonte estará no final do artigo.

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

O próximo ponto é necessário init. Nós da empresa não usamos storyboards, portanto, especificar um inicializador fatal em cada classe do UIView não é totalmente normal. Nesse caso, temos nosso próprio NLView (NL - NibLess) - uma classe na qual init necessário é implementado apenas uma vez. Os novos desenvolvedores do projeto podem não saber disso, mas os benefícios do SwiftLint sempre repreendem, em vez de uma liderança responsável. Ou com isso.

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

Se você ainda estiver usando storyboards, poderá usar as seguintes regras para saber que todos os seus storyboards são privados:

 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 

Muitas vezes acontece que o Foundation é usado onde é completamente desnecessário. Portanto, é melhor destacá-lo sempre, para não esquecer:

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

Espero que todos saibam que a impressão é uma operação bastante difícil, que pode prejudicar bastante o desempenho do aplicativo (especialmente em loops). O único veredicto - as impressões não devem ser de todo.

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

Além disso, você não deve criar protocolos apenas de classe, pois existe a possibilidade de que essa sintaxe fique obsoleta em breve e isso não é recomendado pelos desenvolvedores do Swift .

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

Abaixo está a regra para projetos que usam 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 

Isso é apenas uma pequena parte do que eu poderia criar, mas há ainda menos exemplos na Internet. Você pode ver toda a minha "coleção" no github .

Obrigado pela atenção. Se você também usa o SwiftLint com regras personalizadas, conte-nos sobre elas - ficarei feliz em discutir possíveis casos.

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


All Articles