Adam Rush

@Adam9Rush

18 January, 2022

Linting code is a crucial part of your programming, especially if you’re more than an indie developer. Unfortunately, despite the number of calls you have and agree on how you’re going to format your Swift code, you’ll always get inconsistencies between you and your fellow engineers.

It’s never intentional, but you can be sure that someone has tabs instead of spaces or will put the curly brace on the following line.

Code Linting is a tool that will throw compiler warnings/errors or in-line suggestions based on the rules you set from either the community or among your team.

SwiftLint

SwiftLint is the most popular tool in the iOS community, and the Github repository is open-source, which means the community can define and vote on the rules that people can get by default.

However, you can also define your own custom rules, and you will explore doing that in this tutorial.

Getting Started

You should start by opening your iOS application within Xcode.

You can install SwiftLint using either CocoaPods, HomeBrew or Mint. Let’s go with the recommended way using CocoaPods.

  • Open your PodFile.
pod 'SwiftLint'

You should add the above dependency to your PodFile and run the following command:

pod install

This will go ahead and install SwiftLint as a dependency inside your Xcode Project.

Running SwiftLint on Build

The best way to execute a linting tool is to have it run every time you build the Xcode Project. It means that the SwiftLint rules will be applied every time you compile your code.

  • Open Xcode.
  • Click on the Project file inside your Navigator.
  • Click on your App Target and then click on Build Phases
  • Click on the + sign and click on New Run Script Phase
if which swiftlint >/dev/null; then
  swiftlint
else
  echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi

You should paste this code inside the Run Script.

This code will execute SwiftLint or fail for anyone who is yet to install SwiftLint.

You might want to move SwiftLint elsewhere, or you might want to have this running on CI and outside local development. But having it locally here means that issues are found quickly and locally.

Build your Xcode Project, and SwiftLint will now be active.

SwiftLint Custom Rules

As mentioned previously, the community defines the rules here, and they are changed/improved with a voting system that you can contribute.

However, sometimes your codebase might have specific requirements or not necessarily agree with the community.

In which case, you can define your own custom rules.

You need to create a brand new file inside your project root folder.

cd YourRootFolder
touch .swiftlint.yml

This command will navigate to your project folder and create a new file named swiftlint.yml.

Go ahead and open this new file.

# By default, SwiftLint uses a set of sensible default rules you can adjust:
disabled_rules: # rule identifiers turned on by default to exclude from running
  - colon
  - comma
  - control_statement
opt_in_rules: # some rules are turned off by default, so you need to opt-in
  - empty_count # Find all the available rules by running: `swiftlint rules`

# Alternatively, specify all rules explicitly by uncommenting this option:
# only_rules: # delete `disabled_rules` & `opt_in_rules` if using this
#   - empty_parameters
#   - vertical_whitespace

included: # paths to include during linting. `--path` is ignored if present.
  - Source
excluded: # paths to ignore during linting. Takes precedence over `included`.
  - Carthage
  - Pods
  - Source/ExcludedFolder
  - Source/ExcludedFile.swift
  - Source/*/ExcludedFile.swift # Exclude files with a wildcard
analyzer_rules: # Rules run by `swiftlint analyze` (experimental)
  - explicit_self

# configurable rules can be customized from this configuration file
# binary rules can set their severity level
force_cast: warning # implicitly
force_try:
  severity: warning # explicitly
# rules that have both warning and error levels, can set just the warning level
# implicitly
line_length: 110
# they can set both implicitly with an array
type_body_length:
  - 300 # warning
  - 400 # error
# or they can set both explicitly
file_length:
  warning: 500
  error: 1200
# naming rules can set warnings/errors for min_length and max_length
# additionally they can set excluded names
type_name:
  min_length: 4 # only warning
  max_length: # warning and error
    warning: 40
    error: 50
  excluded: iPhone # excluded via string
  allowed_symbols: ["_"] # these are allowed in type names
identifier_name:
  min_length: # only min_length
    error: 4 # only error
  excluded: # excluded via string array
    - id
    - URL
    - GlobalAPIKey
reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, codeclimate, junit, html, emoji, sonarqube, markdown, github-actions-logging)

This is an example taken directly from SwiftLint with some ideas on customising SwiftLint. Of course, you can go ahead and make some changes.

line_length: 110

file_length:
  warning: 500
  error: 1200

You can go ahead and set the above rules. You have gone with a line length of 110 and a file size of 500-1200 with different levels of warning/error.

This is an excellent example of how you can customise this even further.

Disable Rules

You can also disable specific rules within your codebase, this is super useful if you want to disable a specific piece of code rather than the whole Swift file.

// swiftlint:disable:next line_length

func largeFunction() {
  // Large Function
}

The above example will disable the rule line_length for the next piece of code. You can also disable rules for an entire block of code:

// swiftlint:disable colon

func largeFunction() {

}

func anotherFunction() {

}

// swiftlint:enable colon

Your example above will disable the rule colon for the entire block, but don’t forget to enable it again so the remainder of the file is covered.

What’s Next?

SwiftLint can be a great tool to implement into your workflow; it will make your codebase much more consistent and format the same way for all engineers. It’s about defining the rules with your team and allowing the tooling to create a level of enforcement.

Finally, the CLI tool is convenient, and so I recommend you install this using HomeBrew:

brew install SwiftLint

Sponsor

Subscribe for curated Swift content for free

- weekly delivered.