Code review is an amazing part of the software development process which has so many advantages that it could be a great material for another article. But today I want to focus on how it can be significantly improved by a single tool. How many times, instead of looking for some serious bugs, you were going through checking code style changes? I think that’s unfortunately not such an uncommon situation yet there is a solution to this problem. The first step is to create one consistent code style that will be accepted by your team. But it’s not enough, to assume that memorizing every single rule will solve the problem, we might make mistakes – we’re just human beings!
There are many tools that are designed to solve the problem described, but one in particular really stands out. SwiftLint is a tool for enforcing code and style conventions. It provides a wide range of rules that can be freely customized to our needs.
SwiftLint installation is pretty easy and it can be done in various ways, which you can check out here. In this article, I will show how to do this by using Homebrew but feel free to use any method that suits your needs best. For example, I usually add CocoaPods dependency for test targets to make sure that both developers and CI machine have the same version of SwiftLint installed. In order to install this tool, open the console and run:
When SwiftLint is installed, navigate to your project root directory and you can start to play around with this amazing tool. First of all, run help command to check what options are available. At the very beginning, I suggest running „rules” option that will show a full list of available rules. You will see which rules are enabled by default and which ones are opt-in. It will give you understanding what is evaluated by this tool and which action is performed in case of breaking the rules. For the purpose of this article, I’ve created a new iOS Single View App named „Lint” to demonstrate how to use this tool.
This is the output of running SwiftLint on a brand new Xcode project, but you may wonder why there are warnings even though I haven’t modified this project yet? The answer is not so obvious, default SwiftLint rules are so strict that even clean Xcode project doesn’t comply with all of them. As you can see, this form of presenting warnings isn’t user-friendly and working with such a format on a daily basis could be living hell. Let’s change it!
Navigate to your Xcode project configuration, then open the „Build Phases” tab and add a new „Run Script” phase with this script:
It is copied from SwiftLint documentation and it’s one of the recommended methods of running this tool. After the build phase is added, SwfitLint rules are checked at every build of the application. Moreover, after a build is finished you will see every warning and error next to your code in the IDE. It is very useful because you don’t have to leave your workspace anymore and worry about running rules check.
At first sight, it looks pretty bad, but most of these warnings are easy to fix by removing unnecessary spaces, newlines and comments. After the quick cleanup, almost every warning is gone except one – line length violation caused by UIApplicationDelegate didFinishLaunchingWithOptions method. That’s a great example because it’s quite a common situation when we don’t have full control over the code that is not compliant with the rules.
In order to get rid of the warning or error, you can use a comment with syntax shown above which consist of:
- swiftlint keyword
- enable or disable action
the scope of action – „next”, „previous”, „this” or blank which applies the rule for all lines of the file below comment
You must keep in mind that it is a double-edged sword and it can either help you with 3rd party API’s or be used by lazy developers to remove warnings for a non-compliant code. It is crucial to check if the rule is disabled due to the important reason during the code review process.
A default configuration of SwiftLint rules is quite good, but in my opinion, this tool should help you enforce your own code style in the project instead of making you comply with the default set of rules. Fortunately, you can easily customize SwiftLint rules by adding a .swiftlint.yml file to the root directory of your project.
Steps to create a new rule:
- Update your style guide (it shouldn’t be the decision of one man, but rather a team)
- Update SwiftLint configuration rules to comply with your style guide as much as it’s possible
- Evaluate new rule in practice
Creating your own style guide isn’t necessary, but in the long term, it has many benefits. The code review process will be more impartial and the style guide can serve as part of the onboarding process for the new developers in your team. It can look like a time-consuming task, but if you’re adding rules one by one over an extended period of time you won’t even notice that effort.
This is an example of a .swiftlint.yml configuration file based on the official SwiftLint documentation.
It consists of the following sections:
- Line 1: Disables rules which are enabled by default
- Line 3: Enables Opt-In rules
- Line 6: List of included directories
- Line 8: List of excluded directories
- Line 11: Binary rule that raises either warning or error
- Line 13: Rule that can raise both, warning and error depending on a parameter (file length) value
- Line 17: The Naming rule that can set minimum and maximum length that raises warning or error. It has also a list of excluded names that, for some important reason, shouldn’t comply with this rule.
It’s only a brief overview of available rules configurations but covers most of the popular cases. I suggest you visit the official documentation GitHub page where you can find more sophisticated examples such as creating your own custom rule using a regular expression.
As I’ve stated before, this tool should be used for enforcing an already established code style. However, some of those rules are so helpful on the daily basis that I can’t help myself to suggest you use them :
- Force Try, Force Cast, Force Unwrapping – detects those nasty exclamation marks from your optional values
- Line Length – warns if a line is too long (no more horizontal scrolling during code review!)
- Todo – I don’t know why it isn’t the basic Xcode functionality, but thanks to that rule you won’t miss any TODO anymore
- Large Tuple – helps you avoid passing multiple parameters instead of creating a custom type
- File Length – eliminates all of „God objects” by raising a warning or even an error if file grows too big
Real life projects
After you manage to create complete SwiftLint configuration that suits your code style, there comes the time for implementing it in your projects. In case of new projects it’s not a problem, but what about the existing ones? Usually, this means a lot of refactoring which should be preceded by writing unit tests covering methods that will be affected. Doing it all at once may turn out to be highly unprofitable for the project, therefore unwanted by the business.
To be honest, there is no silver bullet to this problem, but you can overcome it by changing errors into the warnings. By doing so, project will compile with your set of rules and you will maintain the information about the code that breaks them. This approach has the following benefits:
- New functionalities can be implemented with regard to the full set of rules
- Rules are consistent across all of your projects
- Technical debt is easy to detect and track
- Code smells could be removed at the early stage
- Code review requires less time
- Compliance to the code style is verified objectively
- Project maintenance is easier
- Style checks can be part of the CI process
- The code is more readable by using unified code style
- Creating a unified set of rules for many different projects can take a significant amount of time at the initial stage
- Not each rule from your code style can be checked by SwiftLint
SwiftLint is a very powerful, yet easy to use tool designed for Swift developers. It can help you enforce code style and conventions created by your team. Although legacy projects can cause some problems, with a good approach you can overcome them and introduce a new (higher) level of code quality in all of your projects. I encourage you to read official documentation and check the full capabilities of this amazing tool yourself.