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 { }
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.