About static code analyzers and their experience in using iOS mobile applications of the bank

Oleg Ivanov, Head of the Competence Center of Remote Service Channels

Hello! As promised in the article “Mobile Bank from ICD: Development History”, today I want to talk about static code analyzers and the experience of their application in iOS mobile applications of the bank.

Let’s set the goal that we want to achieve using this toolkit:

  • early detection of errors and shortcomings;
  • Code Style (the code design standard is a set of rules and conventions used when writing program code).

A common way to achieve our goals is to manually verify the code – Code review.

The tester or a group of testers carefully examines the code being tested, then they identify errors or sections of the code that may become erroneous in the future, and give recommendations for improving it through comments on the code, which after some time (!) Will be analyzed and corrected by the developer. As we can see, a long and expensive code verification process is emerging. Plus, there is always a human factor – some errors can simply be skipped by reviewers.

Here static code analyzers come to our aid.

Static Code Analyzers – start the automated process of detecting errors and shortcomings in the source code of programs.

Static code analyzers are not a panacea or a replacement for manual Code review, but they are an excellent tool that allows you to reduce the time spent on checking and quickly find patterned errors. The relevance of using static analyzers will only grow over time.

As a static code analyzer in our iOS projects, we use SwiftLint.

SwiftLint is a Swift code auto-checking utility that runs during the build phase of a project. The utility contains a set of rules with the ability to supplement this set with your custom rules. The tool is also used to comply with Code Style.

Why is it important to follow Code Style in the application?
When you are one developer on a project, everything is simple: you write in your own style and you can afford the code in this way:

But when you work in a large development team. an important factor is the speed of understanding and finding the place to insert improvements into someone else’s code.
And here all the team members have to accept the conventions and rules for writing code. But how to check their compliance? The SwiftLint static code analyzer will help us again. And our code will take a nice look that every member of the team will understand:

To get acquainted with the tool, I recommend reading the official the documentation.

Installing SwiftLint is simple:

  1. Add od SwiftLint ‘pod to the project podfile
  2. Add a new “Run Script Phase” to the project.
  3. We determine the SwiftLint ruleset and write them to the .swiftlint.yml configuration file
  4. Add the configuration file .swiftlint.yml to the directory from which we will run SwiftLint

If the SwiftLint embedding project already contained code, you will have to be patient and systematically fix all SwiftLint recommendations. He forms them through the usual error and warning displays with comprehensive tips about the recommendations.

Also in parentheses, it displays the name of the rule that triggered the recommendation. (operator_usage_whitespace).

In this case, it is:

Operator Usage Whitespace
Operators must be surrounded by a single space.

The correct code is:

Recommended Code:

Each rule has a set of attributes:

Identifier: operator_usage_whitespace
Enabled by default: off
Supports Auto Correction: Yes
View: style
Parser rule: Not
Minimum version of the Swift compiler: 3.0.0
Default configuration: warning

Pay attention to “The minimum version of the Swift compiler” – correlate the use of rules with this attribute and with the settings of your project.

Attribute “Default configuration” shows how rules with this attribute will be perceived: either a regular warning, or a compilation error, such as a rule Force cast (Default configuration: error)

All rules can be viewed in a very convenient and illustrated. documentation.

Below I will present the rules that we have chosen in our team, you can use them as an example to create your project.

We divided all the rules into functional and stylistic. – yes, yes, yes, and one space inside each curly brace, and the closing parameters must be on the same line as the opening bracket, and … :). I don’t paint the rules, you can easily find information about them using the link above.


– private_outlet
– force_unwrapping
– force_cast
– force_try
– strong_iboutlet
– private_action
– block_based_kvo
– contains_over_first_not_nil
– discarded_notification_center_observer
– discouraged_direct_init
– discouraged_object_literal
– discouraged_optional_boolean
– discouraged_optional_collection
– duplicate_imports
– dynamic_inline
– empty_count
– empty_parameters
– empty_parentheses_with_trailing_closure
– empty_string
– explicit_enum_raw_value
– function_default_parameter_at_end
– generic_type_name
– identical_operands
– implicit_getter
– is_disjoint
– notification_center_detachment
– nsobject_prefer_isequal
– redundant_set_access_control
– unused_capture_list


– unneeded_parentheses_in_closure_argument
– let_var_whitespace
– yoda_condition
– colon
– comma
– closure_parameter_position
– closure_spacing
– collection_alignment
– leading_whitespace
– mark
– opening_brace
– operator_usage_whitespace
– operator_whitespace
– protocol_property_accessors_order
– return_arrow_whitespace
– switch_case_alignment
– statement_position
– trailing_comma
– trailing_newline
– unneeded_break_in_switch
– custom_rules
– closure_end_indentation
– file_name_no_space
– unowned_variable_capture
– no_space_in_method_call
– contains_over_filter_count
– contains_over_filter_is_empty
– contains_over_range_nil_comparison
– duplicate_enum_cases
– empty_collection_literal

Also, for the purpose of SwiftLint, we chose only the directory with our code base, adding the appropriate setting to the configuration .swiftlint.yml file:


– <каталог кодовой базы>

We created our own rule to prevent the use of the print function. print is a pretty heavy operation. Via the configuration .swiftlint.yml file:

    included: ".*\.swift"
    name: "print usage"
    regex: "((\bprint)|(Swift\.print))\s*\("
    message: "Prefer os_log over print"
    severity: error

This rule prompted us to write our logging function (with a logging level). This logging is used by developers for quick debugging, for example, logs with parameters, request / response body are needed for any analysis of errors, for development. For Release, the log level in our .none version. The remaining use of the print function will result in a build error for the project.

func logApp(level: Constants.LogLevel, items: Any...) {
    if Constants.logLevel == .none {
    if level.rawValue <= Constants.logLevel.rawValue {
        // swiftlint:disable disable_print
        if let strings = items as? [String] {
            for string in strings {
        } else {
        // swiftlunt:enable disable_print

But to use the print function, we had to close its call in our logging function using SwiftLint to ignore our own rules on a code block marked with a special instruction.

// swiftlint:disable disable_print
// swiftlunt:enable disable_print

SwiftLint has the ability to ignore its own rules:

// swiftlint:disable 
<код, который игнорируется SwiftLint для правил rule1 [rule2 rule3…]>
// swiftlunt:enable 


// swiftlint:disable all
<код, который игнорируется SwiftLint для всех правил>
// swiftlint:enable all

Use this opportunity, fully aware that it is necessary!

In conclusion, I note: Using SwiftLint in our team reduced the cost of manual Code review by 20%. Now our reviewers do not pay attention to typical errors (Force Cast, etc.), Code Style and can fully concentrate on checking the new code. Which significantly increased the overall team efficiency (no need to correct such errors checking, these are qualified employees, whose time is very important).

All! Now SwiftLint is forever with you 🙂

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *