Tag: SwiftLint

  • How to add the SwiftLint without pain

    Why do you need SwiftLint?

    1. It speed ups code reviews, you stop wasting time on code formatting, force casting, and other common issues
    2. It improves the code quality, code becomes more readable, and maintainable

    Integration

    1. Add SwiftLint to a podfile

    Or use another option from the official documentation.

      # A tool to enforce Swift style and conventions.
      pod 'SwiftLint', '0.43.1'

    2. Add this .swiftlint.yml config file to the project root folder

    The main trick to make integration easy is to disable all rules at first.

    disabled_rules:
    - trailing_whitespace
    - force_cast
    - force_unwrapping
    - force_try
    - empty_string
    - line_length
    - mark
    - weak_delegate
    - unneeded_break_in_switch
    - identifier_name
    - function_parameter_count
    - unused_closure_parameter
    - vertical_whitespace
    - opening_brace
    - control_statement
    - statement_position
    - comma
    - colon
    - trailing_comma
    
    opt_in_rules:
    - empty_count
    - empty_string
    
    excluded:
    - Carthage
    - Pods
    - SwiftLint/Common/3rdPartyLib
    
    line_length:
        warning: 150
        error: 200
        ignores_function_declarations: true
        ignores_comments: true
        ignores_urls: true
    
    function_body_length:
        warning: 300
        error: 500
    
    function_parameter_count:
        warning: 6
        error: 8
    
    type_body_length:
        warning: 300
        error: 500
    
    file_length:
        warning: 1000
        error: 1500
        ignore_comment_only_lines: true
    
    cyclomatic_complexity:
        warning: 15
        error: 25
    
    reporter: "xcode"

    3. Build a project, add additional rules to the disabled_rules section, if there are many warnings for them

    4. Delete rules from the disabled_rules section one by one and fix all the warnings

    5. Leave the trailing_whitespace and other rules that you don’t want to fix in the disabled_rules section

    In the end, you will have something like this in your config file.

    disabled_rules:
    - trailing_whitespace
    
    opt_in_rules:
    - empty_count
    - empty_string
    
    excluded:
    - Carthage
    - Pods
    - SwiftLint/Common/3rdPartyLib
    
    line_length:
        warning: 150
        error: 200
        ignores_function_declarations: true
        ignores_comments: true
        ignores_urls: true
    
    function_body_length:
        warning: 300
        error: 500
    
    function_parameter_count:
        warning: 6
        error: 8
    
    type_body_length:
        warning: 300
        error: 500
    
    file_length:
        warning: 1000
        error: 1500
        ignore_comment_only_lines: true
    
    cyclomatic_complexity:
        warning: 15
        error: 25
    
    reporter: "xcode"

    Some ideas on how to fix common code issues

    Force Cast Violation: Force casts should be avoided. (force_cast)

    Problem:

    let cell = collectionView.dequeueReusableCell(
        withReuseIdentifier: "DocumentCollectionViewCell",
        for: indexPath
    ) as! DocumentCollectionViewCell
    

    Solution:

    guard let cell = collectionView.dequeueReusableCell(
        withReuseIdentifier: "DocumentCollectionViewCell",
        for: indexPath
    ) as? DocumentCollectionViewCell else { fatalError() }
    

    Force Try Violation: Force tries should be avoided. (force_try)

    Problem:

    let workingDirectory = try! FileManager.default.url(
        for: .documentDirectory,
        in: .userDomainMask,
        appropriateFor: nil,
        create: false
    )
    

    Solution:

    do {
        let workingDirectory = try FileManager.default.url(
            for: .documentDirectory,
            in: .userDomainMask,
            appropriateFor: nil,
            create: false
        )
    } catch {
        print(error)
    }
    

    Exceptions

    In very rare cases you will not be able to fix the warning. For example, when you use a framework and you cannot easily change its API. Then you can switch off a SwiftLint rule for a particular code block using // swiftlint:disable rule_name and // swiftlint:enable rule_name comments.