一、前言
- SwiftLint 是 Realm 推出的一款 Swift 代碼規(guī)范檢查工具释液,SwiftLint 是基于 GitHub 公布的 Swift代碼規(guī)范 對 Swift 代碼進行檢查的腾窝。
- GitHub 公布的 Swift 代碼規(guī)范 - 原文
- GitHub 公布的 Swift 代碼規(guī)范 - 中文
- 配置好 SwiftLint 之后图毕,在 Xcode 中直接編譯代碼硫狞,SwiftLint 就會按照預(yù)先設(shè)置好的代碼規(guī)范自動檢查代碼娄昆,不符合規(guī)范的代碼就會通過
警告(warning)
或者報錯(error)
的形式指示給開發(fā)者烛卧,從而對開發(fā)者的代碼進行規(guī)范佛纫。 - 除了 SwiftLint 自帶的規(guī)則之外,開發(fā)者還可以自定義規(guī)則总放。同時可以禁用或啟用某一些規(guī)則呈宇。
二、安裝 SwiftLint
SwiftLint 可以通過 3 種方式進行安裝:
- 通過 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 安裝,只對單個項目有效尚蝌,如果想要對不同的項目使用不同的
SwiftLint
版本迎变,這會是一種很好的解決方案。 - 需要注意的是使用這種方案會將整個
SwiftLint
以及它的依賴包的完整資源文件都安裝到 Pods/ 目錄中去飘言,所以在使用代碼版本管理工具比如git/svn
時要注意設(shè)置忽略(ignore)相關(guān)目錄衣形。 - 通過 CocoaPods 安裝 SwiftLint,跟安裝第三方框架一樣姿鸿。
- 在項目根目錄創(chuàng)建
Podfile
pod 'SwiftLint'
3谆吴、通過安裝包安裝【全局安裝】
SwiftLint
還支持使用 pkg
安裝包進行安裝,在官方的 GitHub 頁面可以找到最新發(fā)布的安裝包苛预。
SwiftLint 安裝包.png
三句狼、查看 SwiftLint 的全部命令
- 在終端中輸入
swiftlint help
swiftlint help
SwiftLint 的全部命令.png
- 各個命令注釋:
# Automatically correct warnings and errors
# 自動更改警告和錯誤(僅適用于支持自動更改的規(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)
# 打印輸出所有的警告和錯誤
lint
# Display the list of rules and their identifiers
# 顯示所有規(guī)則的列表以及對應(yīng)的 ID
rules
# Display the current version of SwiftLint
# 顯示 SwiftLint 的當前版本號
version
四、SwiftLint 的使用
安裝完成之后热某,需要在Xcode中配置相關(guān)設(shè)置腻菇,才能使 SwiftLint 在 Xcode 中自動檢測代碼規(guī)范胳螟。配置也很簡單,只需要在 Xcode 的 Build Phases 中新建一個 Run Script Phase 配置項筹吐,在里面添加相關(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丘薛,則會報出警告嘉竟,提示團隊成員安裝 SwiftLint
Shell Script Invocation Warning:
warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint
(2)局部腳本的添加
- 局部腳本
"${PODS_ROOT}/SwiftLint/swiftlint"
-
添加局部腳本的步驟
添加局部腳本的步驟.png - 這里其實是設(shè)置了一個自動編譯腳本,每次運行編譯都會自動執(zhí)行這個腳本洋侨。
- 如果正確安裝了 SwiftLint周拐,就會執(zhí)行 SwiftLint 中的代碼規(guī)范檢查,如果沒有安裝凰兑,腳本會拋出一個沒有安裝 SwiftLint 并提示下載的
錯誤
,方便提醒團隊中沒有安裝的成員审丘。
Shell Script Invocation Error:
swiftlint: No such file or directory
- 在沒有安裝 SwiftLint 的情況下吏够,如不想直接報錯,可以使用如下腳本:
"${PODS_ROOT}/SwiftLint/swiftlint"
echo "warning: ..."
2滩报、SwiftLint 的體驗
- 新建一個
SwiftLintDemo
的工程锅知,配置完成后,Command + B
編譯
SwiftLintDemo 新建項目.png - 如圖脓钾,新建項目售睹,任何代碼都沒寫,直接報出一堆
警告
可训,甚至還有錯誤
昌妹。試想,如果是正在開發(fā)中的項目握截,你可能會發(fā)現(xiàn)你的項目提示N+的黃色警告和N+的紅色錯誤飞崖。 - 通過
SwiftLintDemo
,你會發(fā)現(xiàn)甚至一些空格和一些系統(tǒng)的方法和注釋也會報錯或者警告谨胞。 -
SwiftLint
默認方法名或者注釋不得超過120個字符固歪。 - SwiftLint 的所有規(guī)則可以在: Rules 找到。
五胯努、自定義配置
- 當我們編譯一個正在開發(fā)的項目代碼后牢裳,看到的 N 多的警告和錯誤,其實并不全都需要我們來解決叶沛,因為這里面通常包含了第三方庫的代碼規(guī)范問題蒲讯,而且好多問題的級別都被設(shè)置成了
error
。 - 第三方庫的代碼規(guī)范問題恬汁,這不是我們的問題伶椿,怎么解決辜伟?
- 因此,我們需要做一些設(shè)置脊另,讓
SwiftLint
在做代碼規(guī)范檢查的時候自動忽略CocoaPods
导狡、Carthage
等包管理器引入的第三方庫(當然,手動導(dǎo)入的第三方庫也能設(shè)置忽略)偎痛。 - 上面的問題需要我們來
自定義配置文件
旱捧。
1、創(chuàng)建配置文件
首先踩麦,需要在項目的根目錄下新建一個名為
.swiftlint.yml
的配置文件枚赡。打開終端,cd 進入項目根目錄下谓谦。
-
輸入:
touch .swiftlint.yml
創(chuàng)建 .swiftlint.yml文件.png 執(zhí)行完命令之后贫橙,在文件夾中就會有一個
.swiftlint.yml
的隱藏文件。-
隱藏/顯示隱藏文件的命令:
Command + Shift + .
隱藏的配置文件.png 下面來認識一下主要的幾個配置選項
disabled_rules: # 禁用指定的規(guī)則
- colon
- comma
- control_statement
opt_in_rules: # 啟用指定的規(guī)則
- empty_count
- missing_docs
# 可以通過執(zhí)行如下指令來查找所有可用的規(guī)則:
# swiftlint rules
included: # 執(zhí)行 linting 時包含的路徑反粥。如果出現(xiàn)這個 `--path` 會被忽略卢肃。
- Source
excluded: # 執(zhí)行 linting 時忽略的路徑。 優(yōu)先級比 `included` 更高才顿。
- Carthage
- Pods
- Source/ExcludedFolder
- Source/ExcludedFile.swift
2莫湘、在代碼中關(guān)閉某個規(guī)則
- 可以通過在一個源文件中定義一個如下格式的注釋來關(guān)閉這個規(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)用于前一行郑气,當前或者后一行代碼幅垮。
// 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
配置選項用來設(shè)置忽略代碼規(guī)范檢查的路徑尾组,可以指定整個文件夾忙芒。
- 忽略
CocoaPods
引入的第三方庫
excluded:
- Pods
- 如果你的項目中使用
Carthage
管理第三方庫,可以將Carthage
目錄添加到忽略列表:
excluded:
- Pods
- Carthage
- 指定精確路徑下的文件演怎,通過
- xxx
的形式列在下面就可以了匕争。
excluded: # 執(zhí)行 linting 時忽略的路徑。優(yōu)先級比 `included` 更高爷耀。
- Source/ExcludedFolder
- Source/ExcludedFile.swift
4甘桑、嵌套配置
SwiftLint
支持通過嵌套配置文件的方式來對代碼分析過程進行更加細致的控制。
- 在項目的 根
.swiftlint.yml
文件里設(shè)置user_nested_configs: true
值歹叮。 - 在目錄結(jié)構(gòu)必要的地方引入額外的
.swiftlint.yml
文件跑杭。 - 每個文件被檢查時會使用在文件所在目錄下的或者父目錄的更深層目錄下的配置文件。否則根配置文件將會生效咆耿。
-
excluded
德谅,included
和use_nested_configs
在嵌套結(jié)構(gòu)中會被忽略。
5萨螺、自動更正
-
Swiftlint
可以自動修正某些錯誤窄做,磁盤上的文件會被一個修正后的版本覆蓋愧驱。 - 請確保在對文件執(zhí)行
swiftlint autocorrect
之前有對它們做過備份,否則的話有可能導(dǎo)致重要數(shù)據(jù)的丟失椭盏。 - 因為在執(zhí)行自動更正修改某個文件后组砚,很有可能導(dǎo)致之前生成的代碼檢查信息無效或者不正確,所以當在執(zhí)行代碼更正時標準的檢查是無法使用的掏颊。
官方示例
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)