一、前言
- SwiftLint 是 Realm 推出的一款 Swift 代碼規(guī)范檢查工具,SwiftLint 是基于 GitHub 公布的 Swift代碼規(guī)范 對 Swift 代碼進(jìn)行檢查的。
- GitHub 公布的 Swift 代碼規(guī)范 - 原文
- GitHub 公布的 Swift 代碼規(guī)范 - 中文
- 配置好 SwiftLint 之后,在 Xcode 中直接編譯代碼,SwiftLint 就會按照預(yù)先設(shè)置好的代碼規(guī)范自動檢查代碼,不符合規(guī)范的代碼就會通過
警告(warning)或者報(bào)錯(cuò)(error)的形式指示給開發(fā)者,從而對開發(fā)者的代碼進(jìn)行規(guī)范。 - 除了 SwiftLint 自帶的規(guī)則之外,開發(fā)者還可以自定義規(guī)則。同時(shí)可以禁用或啟用某一些規(guī)則。
二、安裝 SwiftLint
SwiftLint 可以通過 3 種方式進(jìn)行安裝:
- 通過 HomeBrew 安裝
- 通過 CocoaPods 安裝
- 通過 pkg 安裝包安裝
1、通過 Homebrew 安裝【全局安裝】
- 第一步: 安裝 Homebrew (如已安裝,請?zhí)^)
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
如果出現(xiàn)下圖所示,表示 Homebrew 安裝成功。

Homebrew安裝成功.png
- 第二步: 通過終端命令安裝 SwiftLint
brew install SwiftLint

SwiftLint 安裝成功.png
2、通過 CocoaPods 安裝【局部安裝】
- 通過 CocoaPods 安裝,只對單個(gè)項(xiàng)目有效,如果想要對不同的項(xiàng)目使用不同的
SwiftLint版本,這會是一種很好的解決方案。 - 需要注意的是使用這種方案會將整個(gè)
SwiftLint以及它的依賴包的完整資源文件都安裝到 Pods/ 目錄中去,所以在使用代碼版本管理工具比如git/svn時(shí)要注意設(shè)置忽略(ignore)相關(guān)目錄。 - 通過 CocoaPods 安裝 SwiftLint,跟安裝第三方框架一樣。
- 在項(xiàng)目根目錄創(chuàng)建
Podfile
pod 'SwiftLint'
3、通過安裝包安裝【全局安裝】
SwiftLint 還支持使用 pkg 安裝包進(jìn)行安裝,在官方的 GitHub 頁面可以找到最新發(fā)布的安裝包。

SwiftLint 安裝包.png
三、查看 SwiftLint 的全部命令
- 在終端中輸入
swiftlint help
swiftlint help

SwiftLint 的全部命令.png
- 各個(gè)命令注釋:
# Automatically correct warnings and errors
# 自動更改警告和錯(cuò)誤(僅適用于支持自動更改的規(guī)則)
autocorrect
# Generates markdown documentation for all rules
# 為所有規(guī)則生成 markdown 文檔
generate-docs
# Display general or command-specific help
# 顯示通用命令或指定命令的幫助信息
help
# Print lint warnings and errors (default command)
# 打印輸出所有的警告和錯(cuò)誤
lint
# Display the list of rules and their identifiers
# 顯示所有規(guī)則的列表以及對應(yīng)的 ID
rules
# Display the current version of SwiftLint
# 顯示 SwiftLint 的當(dāng)前版本號
version
四、SwiftLint 的使用
安裝完成之后,需要在Xcode中配置相關(guān)設(shè)置,才能使 SwiftLint 在 Xcode 中自動檢測代碼規(guī)范。配置也很簡單,只需要在 Xcode 的 Build Phases 中新建一個(gè) Run Script Phase 配置項(xiàng),在里面添加相關(guān)代碼后,編譯即可!
1、SwiftLint 腳本設(shè)置
- 這里分兩種情況: 全局腳本的添加 和 局部腳本的添加。
(1)全局腳本的添加
- 全局腳本
if which swiftlint >/dev/null; then
swiftlint
else
echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi
-
添加全局腳本的步驟
添加全局腳本的步驟.png - 如果沒有安裝 SwiftLint,則會報(bào)出警告,提示團(tuán)隊(duì)成員安裝 SwiftLint
Shell Script Invocation Warning:
warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint
(2)局部腳本的添加
- 局部腳本
"${PODS_ROOT}/SwiftLint/swiftlint"
-
添加局部腳本的步驟
添加局部腳本的步驟.png - 這里其實(shí)是設(shè)置了一個(gè)自動編譯腳本,每次運(yùn)行編譯都會自動執(zhí)行這個(gè)腳本。
- 如果正確安裝了 SwiftLint,就會執(zhí)行 SwiftLint 中的代碼規(guī)范檢查,如果沒有安裝,腳本會拋出一個(gè)沒有安裝 SwiftLint 并提示下載的
錯(cuò)誤,方便提醒團(tuán)隊(duì)中沒有安裝的成員。
Shell Script Invocation Error:
swiftlint: No such file or directory
- 在沒有安裝 SwiftLint 的情況下,如不想直接報(bào)錯(cuò),可以使用如下腳本:
"${PODS_ROOT}/SwiftLint/swiftlint"
echo "warning: ..."
2、SwiftLint 的體驗(yàn)
- 新建一個(gè)
SwiftLintDemo的工程,配置完成后,Command + B編譯
SwiftLintDemo 新建項(xiàng)目.png - 如圖,新建項(xiàng)目,任何代碼都沒寫,直接報(bào)出一堆
警告,甚至還有錯(cuò)誤。試想,如果是正在開發(fā)中的項(xiàng)目,你可能會發(fā)現(xiàn)你的項(xiàng)目提示N+的黃色警告和N+的紅色錯(cuò)誤。 - 通過
SwiftLintDemo,你會發(fā)現(xiàn)甚至一些空格和一些系統(tǒng)的方法和注釋也會報(bào)錯(cuò)或者警告。 -
SwiftLint默認(rèn)方法名或者注釋不得超過120個(gè)字符。 - SwiftLint 的所有規(guī)則可以在: Rules 找到。
五、自定義配置
- 當(dāng)我們編譯一個(gè)正在開發(fā)的項(xiàng)目代碼后,看到的 N 多的警告和錯(cuò)誤,其實(shí)并不全都需要我們來解決,因?yàn)檫@里面通常包含了第三方庫的代碼規(guī)范問題,而且好多問題的級別都被設(shè)置成了
error。 - 第三方庫的代碼規(guī)范問題,這不是我們的問題,怎么解決?
- 因此,我們需要做一些設(shè)置,讓
SwiftLint在做代碼規(guī)范檢查的時(shí)候自動忽略CocoaPods、Carthage等包管理器引入的第三方庫(當(dāng)然,手動導(dǎo)入的第三方庫也能設(shè)置忽略)。 - 上面的問題需要我們來
自定義配置文件。
1、創(chuàng)建配置文件
首先,需要在項(xiàng)目的根目錄下新建一個(gè)名為
.swiftlint.yml的配置文件。打開終端,cd 進(jìn)入項(xiàng)目根目錄下。
-
輸入:
touch .swiftlint.yml
創(chuàng)建 .swiftlint.yml文件.png 執(zhí)行完命令之后,在文件夾中就會有一個(gè)
.swiftlint.yml的隱藏文件。-
隱藏/顯示隱藏文件的命令:
Command + Shift + .
隱藏的配置文件.png 下面來認(rèn)識一下主要的幾個(gè)配置選項(xiàng)
disabled_rules: # 禁用指定的規(guī)則
- colon
- comma
- control_statement
opt_in_rules: # 啟用指定的規(guī)則
- empty_count
- missing_docs
# 可以通過執(zhí)行如下指令來查找所有可用的規(guī)則:
# swiftlint rules
included: # 執(zhí)行 linting 時(shí)包含的路徑。如果出現(xiàn)這個(gè) `--path` 會被忽略。
- Source
excluded: # 執(zhí)行 linting 時(shí)忽略的路徑。 優(yōu)先級比 `included` 更高。
- Carthage
- Pods
- Source/ExcludedFolder
- Source/ExcludedFile.swift
2、在代碼中關(guān)閉某個(gè)規(guī)則
- 可以通過在一個(gè)源文件中定義一個(gè)如下格式的注釋來關(guān)閉這個(gè)規(guī)則
// swiftlint:disable <rule>
- 在該文件結(jié)束之前或者在定義如下格式的匹配注釋之前,這條規(guī)則都會被禁用:
// swiftlint:enable <rule>
- 舉例:
viewDidLoad方法后面的圓括號 () 跟 大括號 { 貼在了一起
// swiftlint:disable opening_brace
override func viewDidLoad(){
// swiftlint:enable opening_brace
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
規(guī)則關(guān)閉之前:

規(guī)則關(guān)閉之前.png
規(guī)則關(guān)閉之后:

規(guī)則關(guān)閉之后.png
- 也可以通過添加 :previous, :this 或者 :next 來使關(guān)閉或者打開某條規(guī)則的命令分別應(yīng)用于前一行,當(dāng)前或者后一行代碼。
// swiftlint:disable:next force_cast
let noWarning = NSNumber() as! Int
let hasWarning = NSNumber() as! Int
let noWarning2 = NSNumber() as! Int // swiftlint:disable:this force_cast
let noWarning3 = NSNumber() as! Int
// swiftlint:disable:previous force_cast
規(guī)則關(guān)閉之前:

規(guī)則關(guān)閉之前.png
規(guī)則關(guān)閉之后:

規(guī)則關(guān)閉之后.png
3、忽略引入的第三方庫
excluded 配置選項(xiàng)用來設(shè)置忽略代碼規(guī)范檢查的路徑,可以指定整個(gè)文件夾。
- 忽略
CocoaPods引入的第三方庫
excluded:
- Pods
- 如果你的項(xiàng)目中使用
Carthage管理第三方庫,可以將Carthage目錄添加到忽略列表:
excluded:
- Pods
- Carthage
- 指定精確路徑下的文件,通過
- xxx的形式列在下面就可以了。
excluded: # 執(zhí)行 linting 時(shí)忽略的路徑。優(yōu)先級比 `included` 更高。
- Source/ExcludedFolder
- Source/ExcludedFile.swift
4、嵌套配置
SwiftLint 支持通過嵌套配置文件的方式來對代碼分析過程進(jìn)行更加細(xì)致的控制。
- 在項(xiàng)目的 根
.swiftlint.yml文件里設(shè)置user_nested_configs: true值。 - 在目錄結(jié)構(gòu)必要的地方引入額外的
.swiftlint.yml文件。 - 每個(gè)文件被檢查時(shí)會使用在文件所在目錄下的或者父目錄的更深層目錄下的配置文件。否則根配置文件將會生效。
-
excluded,included和use_nested_configs在嵌套結(jié)構(gòu)中會被忽略。
5、自動更正
-
Swiftlint可以自動修正某些錯(cuò)誤,磁盤上的文件會被一個(gè)修正后的版本覆蓋。 - 請確保在對文件執(zhí)行
swiftlint autocorrect之前有對它們做過備份,否則的話有可能導(dǎo)致重要數(shù)據(jù)的丟失。 - 因?yàn)樵趫?zhí)行自動更正修改某個(gè)文件后,很有可能導(dǎo)致之前生成的代碼檢查信息無效或者不正確,所以當(dāng)在執(zhí)行代碼更正時(shí)標(biāo)準(zhǔn)的檢查是無法使用的。
官方示例
disabled_rules: # rule identifiers to exclude from running
- colon
- comma
- control_statement
opt_in_rules: # some rules are only opt-in
- empty_count
# Find all the available rules by running:
# swiftlint rules
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
# 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
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, junit, html, emoji)




