SwiftLint Getting Started Part 1
In this blog I will cover the following topics
- What is Lint,SwiftLint and Static Source Code Analysis?
- Benefits of Using SwiftLint
- Custom Configuration
- SwiftLint Analyzer
In part 2 we will see different ways to integrate Swiftlint with Source Control
Lint
Lint, or a linter, is a tool that analyzes source code to flag programming errors, bugs, stylistic errors, and suspicious constructs (likely to become error) OR
The process (and tools) of applying rules against a codebase and flagging code structures that violate these rules.
SwiftLint
A static source code analysis tool to enforce Swift style and conventions.The GitHub’s Swift Style Guide was taken as a basic rule OR
SwiftLint, is a tool that analyzes Swift source code to flag programming errors, bugs, stylistic errors, and suspicious constructs (likely to become error)
Static Source Code Analysis?
Static analysis is best described as a method of debugging by automatically examining source code before a program is run (like a code review by a tool / automated code review)
Benefits
- A linter can help to avoid errors, and things that could not be errors (but look like them) or could be potentially dangerous.
- Uniform coding style across the team
- Pre-code review
- Readability
Installation
Install it via cocoapods see this link. Make sure you add this script in you Run script under Build phases tab as shown in Figure 1. Since we will be executing Swiftlint command through terminal I will recommend you to install in your machine as well using homeBrew see this link.
Xcode offers the possibility to run user defined code as part of the build process using the “Run Script Phase” in the “Build Phases” section.
At this point we Integrated SwiftLint into an Xcode scheme to get warnings and errors displayed in the IDE everytime build process
SwiftLint version
You should always run SwiftLint with the same toolchain you use to compile your code as shown in Figure 2
Getting Started
After setup swiftlint in an existing application in my case I got 130 error as shown in Figure 3
Configuration
Swiftlint is working as shown in Figure 3 but it is analyzing the rules in the whole application we only want analysis of code we wrote this is where configuration will play its role. We Configure SwiftLint by adding a .swiftlint.yml
file from the directory you'll run SwiftLint from.
As shown in Figure 4 we configured swiftlint not to look these directories. So it will not apply lint to all the Pods installed in the project
Alternative you can specify directories to look only to Swiftlint . It will not look into the folder specify in both included and excluded list Since excluded keyword have higher priorities over included. Note: BuildPhases
is the name of the application
You can find an updated list of rules and more information about them in Rules.md. Some rules are enable or disable by default, we can alter this behaviour in the config file. As shown in Figure 6 force_try
enable by default whereas force_unwrapping
disable by default.
As shown in Figure 6 since force_try
enable by default and when you run the application build will not succeed since you are violating this rule. There may be cases where you need to do force try according to the use case
Use Case 1 (Disable Completely)
disabled_rules →
Disable rules keyword from the default enabled set.
As shown in Figure 8 we disabled force_try
rule completely and now application will build successfully
Use Case 2 (Disable Rule in One File Only)
Sometimes you want to enable rule throughout the target but in one file you want to disable it . Add this line in the top of the file // swiftlint:disable force_try
. The rules will be disabled until the end of the file or // swiftlint:enable force_try
linter see this line
Make sure you remove it from .yml
file fromdisabled_rules
keyword. As shown in Figure 9 it disabled this rule within this file which is ViewController.swift
Opt-In Rules
opt_in_rules
are disabled by default (i.e., you have to explicitly enable them in your configuration file).
As shown in Figure 6 force_unwrapping
rule is disabled by default if you don’t follow this rule Swiftlint will not enforce you until and unless you explicitly enabled this rule in the config file
As shown in Figure 10.1 we enabled force_unwrapping
rule in the configuration file under the keyword opt_in_rules
and as shown in Figure 10.2 Swiftlint warn us that we are breaking force_unwrapping
rule
As shown in Figure 10.2 Swiftlint show warning when you don’t follow this rule you can change the severity level as well in the config file
As shown in Figure 11 force_unwrapping
by default show warning
(if enable) and we config it to show error
instead of warning
. In the same way force_try
by default show error
(if enable) and we config it to show warning
instead of error
as shown in Figure 12
whitelist_rules
Acts as a whitelist, only the rules specified in this list will be enabled. Can not be specified alongside
disabled_rules
oropt_in_rules
As shown in Figure 13 we enable only force_unwrapping
rule and disabled all rules irrespective of whether particular rule enable by default or not. One thing to note I commented out disabled_rules
and opt_in_rules
because as told above if you use whitelist_rules
you can’t use these one otherwise your config file will fail to load
analyzer_rules
This is an entirely separate list of rules that are only run by the
analyze
command. All analyzer rules are opt-in,means disabled by default we need to enable it in config file
Note: This command and related code in SwiftLint is subject to substantial changes at any time while this feature is marked asexperimental
. Analyzer rules also tend to be considerably slower than lint rules.
Go to the rules documentation
and you will see explicit_self
is the rule that will run by the analyze command and the only option to enable this rule is to specify under the analyzer_rules
keyword in the config file as shown in Figure 14
As shown in Figure 15 we are voting explicit_self rule still no error/warning and the answer is
The experimental
swiftlint analyze
command can lint Swift files using the full type-checked AST. The compiler log path containing the cleanswiftc
build command invocation (incremental builds will fail) must be passed toanalyze
via the--compiler-log-path
flag. e.g.--compiler-log-path /path/to/xcodebuild.log.
Analyze Command Usage
- Delete the derived data
- Go to the Project root folder
- Run command
xcodebuild -workspace BuildPhases.xcworkspace -scheme BuildPhases -configuration Debug CODE_SIGN_IDENTITY=”” CODE_SIGNING_REQUIRED=NO > xcodebuild.log
- You will see xcodebuild.log file in the project directory
- Run this command in the same folder
swiftlint analyze — compiler-log-path xcodebuild.log
- As in the terminal analyzer telling us that we are breaking
explicit_self
in 25,26 and 33 line of the classViewController
line_length
→ This rule is enabled by default and the rule says Lines should not span too many characters. This rule can be configure as well type_body_length
→ This rule is enabled by default and the rule says Type (class , Struct , enum , Protocol )bodies should not span too many lines. This rule can be configure as well where you can specify threshold when to show warning and when to show error
file_length
→ This rule is enabled by default and the rule says Files should not span too many lines. This rule can be configure as well
Note: You can create your custom rule as well by specifying regex see this link
Useful Links
https://github.com/realm/SwiftLint/blob/master/Rules.md#force-unwrapping
https://github.com/realm/SwiftLint/tree/master/Source/SwiftLintFramework/Rules
https://github.com/realm/SwiftLint