Powered By Blogger

Thursday, March 16, 2017

How to integrate "SwiftLint" library into XCode project ?


Hi everyone,

Now a days, I was looking for a tool which can assist the developers to write code with good quality by following some basic standards. A tool which can throws warnings/errors if developer is not following the code writing rules. I have found multiple tools for multiple platforms. But I have chosen "SwiftLint" for "SWIFT" language, which is the same as its prior version "OCLint" for "Objective C".

A) Steps to integrate :



Please read this article's contents carefully to integrate it successfully and below are the steps :

Step 1 : Install ‘Homebrew’ into your Mac using the below command :

a. /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Step 2 : Install ‘SwiftLint’ package with the help of below command :

a. brew install swiftlint

Step 3 : To Integrate SwiftLint into current Xcode Project, add a new “Run Script” in Build phase with below contents :

if which swiftlint >/dev/null; then
swiftlint
else
echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi

Note 1 : Above code will throw a warning if SwiftLint is not installed on the system. But if you want that all your team member will install it, you can make build failed using following script :

if which swiftlint >/dev/null; then
swiftlint
else
echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
exit 1
fi

Note 2 : Now build your project (⌘B). SwiftLint will automatically identify warnings and errors in your code that does not comply with the default style guide line. Finally we have successfully integrated SwiftLint in our current project. But, If you will compile your project, you ended up with lots of warnings and errors. Even Xcode’s “Single View” project template doesn’t pass SwiftLint’s default validation.


B) Auto correct:


Some of the basic issues (such as whitespace at the end of a line) can be automatically fixed by SwiftLint. Just open the terminal and type the following command in your project root directory.

$ cd path/to/project/root/directory
$ swiftlint autocorrect
$ swiftlint autocorrect --path your_file.swift #For SwiftLint's auto correct on single file


C) To configure the behaviour of SwiftLint :


Now we have to fix all other issues that SwiftLint’s autocorrect was not able to do. But fixing all the issues one time it’s too much complex and time consuming. Fortunately, it provides configuration options to ‘enable/disable’ its pre defined rules. So, Initially I will disable all the rules and enable one by one to break down the bigger task into smaller chunks.


To get started, just create '.swiftlint.yml' in your project’s root directory and paste following contents in it.

disabled_rules:
- trailing_newline
- opening_brace
- empty_count
- comma
- colon
- force_cast
- type_name
- variable_name_min_length
- trailing_semicolon
- force_try
- function_body_length
- nesting
- variable_name
- conditional_binding_cascade
- variable_name_max_length
- operator_whitespace
- control_statement
- legacy_constant
- line_length
- return_arrow_whitespace
- trailing_whitespace
- closing_brace
- statement_position
- type_body_length
- todo
- legacy_constructor
- valid_docs
- missing_docs
- file_length
- leading_whitespace

- Some rules have parameters that you can configure, for example the Type Body Length, how many lines of code the body of a type is allowed to be, can be configured like this:

type_body_length:
- 300 # warning
- 400 # error

D) Summary points :

- To list all available SwiftLint’s rules type following command : ‘$ swiftlint rules’

a) All available rules which you can use are here.

b) You can download the example configuration file from here.

c) Followings are the valid rule identifiers, you can use any of them :
(empty_count , redundant_optional_initialization , trailing_semicolon , statement_position , type_name , unused_enumerated , todo , legacy_constant , force_cast , unused_closure_parameter , nimble_operator , number_separator , comma , sorted_imports , implicit_getter , legacy_cggeometry_functions , force_unwrapping , leading_whitespace , cyclomatic_complexity , control_statement , function_body_length , empty_parentheses_with_trailing_closure , dynamic_inline , type_body_length , unused_optional_binding , operator_whitespace , closure_spacing , prohibited_super_call , object_literal , valid_docs , vertical_whitespace , redundant_void_return , large_tuple , trailing_whitespace , mark , empty_parameters , legacy_nsgeometry_functions , shorthand_operator , closing_brace , class_delegate_protocol , colon , closure_parameter_position , nesting , switch_case_on_newline , file_header , conditional_returns_on_newline , trailing_newline , missing_docs , variable_name , redundant_nil_coalescing , private_unit_test , compiler_protocol_init , return_arrow_whitespace , operator_usage_whitespace , attributes , overridden_super_call , vertical_parameter_alignment , first_where , private_outlet , generic_type_name , explicit_init , legacy_constructor , closure_end_indentation , custom_rules , function_parameter_count , syntactic_sugar , trailing_comma , void_return , valid_ibinspectable , opening_brace , line_length , weak_delegate , force_try , redundant_string_enum_value , file_length)


Regards,
Nilesh