SwiftLint Getting Started Part 1

https://plugins.jetbrains.com/plugin/9175-swiftlint

In this blog I will cover the following topics

  1. What is Lint,SwiftLint and Static Source Code Analysis?
  2. Benefits of Using SwiftLint
  3. Custom Configuration
  4. 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

  1. A linter can help to avoid errors, and things that could not be errors (but look like them) or could be potentially dangerous.
  2. Uniform coding style across the team
  3. Pre-code review
  4. 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

Figure 1

SwiftLint version

You should always run SwiftLint with the same toolchain you use to compile your code as shown in Figure 2

to use for a given Swift version.
Figure 2

Getting Started

After setup swiftlint in an existing application in my case I got 130 error as shown in Figure 3

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

Figure 4

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

Figure 5

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.

Figure 6

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

Figure 7

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

Figure 8

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

Figure 9

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_unwrappingrule 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

Figure 10.1
Figure 10.2

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

Figure 11
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 or opt_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

Figure 13

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 as experimental. 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

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 clean swiftc build command invocation (incremental builds will fail) must be passed to analyze via the --compiler-log-path flag. e.g. --compiler-log-path /path/to/xcodebuild.log.

Figure 15

Analyze Command Usage

  1. Delete the derived data
  2. Go to the Project root folder
  3. Run command xcodebuild -workspace BuildPhases.xcworkspace -scheme BuildPhases -configuration Debug CODE_SIGN_IDENTITY=”” CODE_SIGNING_REQUIRED=NO > xcodebuild.log
  4. You will see xcodebuild.log file in the project directory
  5. Run this command in the same folder swiftlint analyze — compiler-log-path xcodebuild.log
  6. As in the terminal analyzer telling us that we are breaking explicit_self in 25,26 and 33 line of the class ViewController
Figure 16.1
Figure 16.2

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

Figure 17

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