Xcode代碼規(guī)范之SwiftLint配置
前言
- 最近公司大佬考慮將項(xiàng)目代碼規(guī)范化, 然而自Xcode9之后,Xcode的插件基本處于廢棄的狀態(tài)大部分插件都是在一年前就停止更新了;
- 于是在谷歌找到了一款強(qiáng)大的代碼規(guī)范工具SwiftLint
- SwiftLint是 Realm 推出的一款 Swift 代碼規(guī)范檢查工具, SwiftLint 基于 Github 公布的 Swift 代碼規(guī)范進(jìn)行代碼檢查,并且能夠很好的和 Xcode 整合
- Github 公布的 Swift 代碼規(guī)范--原文
- Github 公布的 Swift 代碼規(guī)范--中文
- 配置好所有的設(shè)置之后,在 Xcode 中執(zhí)行編譯時(shí),SwiftLint 會(huì)自動(dòng)運(yùn)行檢查,不符合規(guī)范的代碼會(huì)通過警告或者 紅色錯(cuò)誤 的形式指示出來
- 支持自定義規(guī)則,可禁用或者開啟某一些規(guī)則
一. 安裝SwiftLint
- SwiftLint目前有三種安裝方式可供選擇,可以根據(jù)自己的項(xiàng)目需要自行選擇
1. 安裝全局配置(Homebrew 安裝)
Homebrew
- Homebrew, Mac系統(tǒng)的包管理器,用于安裝NodeJS和一些其他必需的工具軟件, 輸入以下代碼安裝:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
譯注:在Max OS X 10.11(El Capitan)版本中,homebrew在安裝軟件時(shí)可能會(huì)碰到/usr/local目錄不可寫的權(quán)限問題。可以使用下面的命令修復(fù):
sudo chown -R `whoami` /usr/local
- Homebrew 會(huì)自動(dòng)安裝最新版本
- 打開終端輸入以下代碼:
brew install swiftlint
安裝成功,如下圖所示:

2. 使用 CocoaPods 安裝
- 這種方式只能針對(duì)單個(gè)項(xiàng)目有效,如果你想要針對(duì)不同的項(xiàng)目使用不同的
SwiftLint版本,這是一種很好的解決方案 - 需要注意的是使用這種方案會(huì)將整個(gè)
SwiftLint以及他的依賴包的完整資源文件都安裝到 Pods/ 目錄中去,所以在使用版本管理工具比如git/svn時(shí)要注意設(shè)置忽略相關(guān)目錄 - CocosPods安裝和安裝第三方框架一樣
- 在根目錄創(chuàng)建
Podfile
pod 'SwiftLint'
3. 使用安裝包
SwiftLint 還支持使用 pkg 安裝包進(jìn)行安裝,在官方的 Github 頁面可以找到最新發(fā)布的安裝包
二. 查看SwiftLint的全部命令
- 等待安裝完成,在終端輸入
swiftlint help可以查看所有可用的命令:

各個(gè)命令注釋
//查看所有命令
swiftlint help
//忽略空格導(dǎo)致的警告和錯(cuò)誤
swiftlint autocorrect
//輸出所有的警告和錯(cuò)誤
swiftlint lint
//查看所有可獲得的規(guī)則以及對(duì)應(yīng)的 ID
swiftlint rules
//產(chǎn)看當(dāng)前版本號(hào)
swiftlint version
- 我們將目錄切換到工程的根目錄之下,然后敲擊如下命令:
swiftlint autocorrect
然后我們就會(huì)發(fā)現(xiàn),所有的空格符Warning都消失了。這都得益于我們剛剛所進(jìn)行的命令行操作,它會(huì)將已知的能夠自動(dòng)修復(fù)的Error和Warning都自動(dòng)修復(fù),大大的減輕了我們的工作量。
三. SwiftLint的使用
安裝完成后,需要在Xcode中配置相關(guān)設(shè)置,才能使 SwiftLint 在 Xcode 中自動(dòng)檢測(cè)代碼規(guī)范。配置也很簡(jiǎn)單,只需要在 Xcode 的 Build Phases 中新建一個(gè) Run Script Phase 配置項(xiàng),在里面添加相關(guān)代碼后,編譯即可!
- 配置代碼添加步驟
- 需要將相關(guān)腳本添加到紅色框內(nèi)

1. 全局安裝腳本添加方式
if which swiftlint >/dev/null; then
swiftlint
else
echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi
2. CocoaPods安裝腳本添加
"${PODS_ROOT}/SwiftLint/swiftlint"
- 這里其實(shí)是設(shè)置了一個(gè)自動(dòng)編譯腳本,每次運(yùn)行編譯都會(huì)自動(dòng)執(zhí)行這個(gè)腳本
- 如果正確安裝了 SwiftLint,就會(huì)執(zhí)行 SwiftLint 中的代碼規(guī)范檢查,如果沒有安裝,腳本會(huì)拋出一個(gè)沒有安裝 SwiftLint 并提示下載的警告,方便提醒團(tuán)隊(duì)團(tuán)隊(duì)中沒有安裝的成員。
- 當(dāng)然,你也可以設(shè)置為強(qiáng)制要求安裝,這時(shí)如果沒有安裝則無法通過編譯。只需要在腳本中
echo "warning: ..."
之后添加一行代碼:
exit 1
- 這樣一來,如果沒有安裝 SwiftLint,編譯時(shí)會(huì)直接拋出一個(gè)編譯錯(cuò)誤而非警告,提示需要安裝 SwiftLint。
3. 配置完成后,command+B編譯
- 如果你的是正在開發(fā)中的項(xiàng)目, 你可能會(huì)發(fā)現(xiàn)你的項(xiàng)目提示999+的黃色警告和999+的紅色錯(cuò)誤
- 甚至你會(huì)發(fā)現(xiàn)甚至一些空格和一些系統(tǒng)的方法和注釋也會(huì)報(bào)錯(cuò)或者警告
-
SwiftLint默認(rèn)方法名或者注釋不得超過120個(gè)字符

- Swift Lint 在完成上述操作之后,便已經(jīng)生效。但是,如果覺得默認(rèn)的風(fēng)格過于嚴(yán)格,或者項(xiàng)目組有另外的要求,Swift Lint 也可以定制相應(yīng)的風(fēng)格,或者禁用某些規(guī)則。
- SwiftLint 的全部規(guī)則可以在:Source/SwiftLintFramework/Rules 目錄內(nèi)找到
四. 自定義配置
- 當(dāng)你編譯過項(xiàng)目后,看到999+的警告和錯(cuò)誤,是不是第一反應(yīng)就是要放棄了,其實(shí)不然
- 仔細(xì)看一下具體的錯(cuò)誤,會(huì)發(fā)現(xiàn)好多都是第三方庫的代碼規(guī)范問題,而且好多問題的級(jí)別被設(shè)置成為了 error
- 第三方庫的代碼規(guī)范問題,這個(gè)鍋我們可不能背
- 這里我們可以做一些配置,讓
SwiftLint在做代碼規(guī)范檢查的時(shí)候自動(dòng)忽略CocoaPods、Carthage等包管理器引入的第三方庫(當(dāng)然,手動(dòng)導(dǎo)入的第三方庫也能設(shè)置忽略)
1. 創(chuàng)建配置文件
- 首先需要在項(xiàng)目的根目錄下新建一個(gè)名為 .swiftlint.yml 的配置文件
- 打開終端, cd 到項(xiàng)目根目錄下
- 輸入:
touch .swiftlint.yml - 執(zhí)行完該命令后, 在文件夾中你可能找不到該yml格式文件,那是因?yàn)槲募浑[藏了
- 關(guān)于隱藏/顯示隱藏文件(命令一樣):
command + shift + . - 下面我們來認(rèn)識(shí)一下主要的幾個(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` 會(huì)被忽略。
- Source
excluded: # 執(zhí)行 linting 時(shí)忽略的路徑。 優(yōu)先級(jí)比 `included` 更高。
- Carthage
- Pods
- Source/ExcludedFolder
- Source/ExcludedFile.swift
2. 在代碼中關(guān)閉某個(gè)規(guī)則
可以通過在一個(gè)源文件中定義一個(gè)如下格式的注釋來關(guān)閉某個(gè)規(guī)則:
// swiftlint:disable <rule>
在該文件結(jié)束之前或者在定義如下格式的匹配注釋之前,這條規(guī)則都會(huì)被禁用:
// swiftlint:enable <rule>
例如:
// swiftlint:disable opening_brace
func initTakeScreenshot(launchOptions: [AnyHashable: Any]?){
// swiftlint:enable opening_brace
if let options = launchOptions {
let userInfo = options[UIApplicationLaunchOptionsKey.remoteNotification]
NotificationCenter.default.post(name: Notification.Name.UIApplicationUserDidTakeScreenshot, object: userInfo)
}
}
規(guī)則關(guān)閉之前

規(guī)則關(guān)閉之后

也可以通過添加 :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
3. 忽略引入的第三方庫
- 1). 忽略
CocoaPods導(dǎo)入的第三方庫
excluded:
- Pods
- 2). excluded 配置項(xiàng)用來設(shè)置忽略代碼規(guī)范檢查的路徑,可以指定整個(gè)文件夾
- 比如如果你的項(xiàng)目使用 Carthage 管理第三方庫的話,可以將 Carthage 目錄添加到忽略列表:
excluded:
- Pods
- Carthage
- 3). 指定精確路徑下的文件,通過 - xxxx 的形式列在下面就可以了
excluded: # 執(zhí)行 linting 時(shí)忽略的路徑。 優(yōu)先級(jí)比 `included` 更高。
- Source/ExcludedFolder
- Source/ExcludedFile.swift
4. 嵌套配置
SwiftLint 支持通過嵌套配置文件的方式來對(duì)代碼分析過程進(jìn)行更加細(xì)致的控制。
- 在你的根
.swiftlint.yml文件里設(shè)置use_nested_configs: true值。 - 在目錄結(jié)構(gòu)必要的地方引入額外的
.swiftlint.yml文件。 - 每個(gè)文件被檢查時(shí)會(huì)使用在文件所在目錄下的或者父目錄的更深層目錄下的配置文件。否則根配置文件將會(huì)生效。
-
excluded,included,和use_nested_configs在嵌套結(jié)構(gòu)中會(huì)被忽略。
5. 自動(dòng)更正
-
SwiftLint可以自動(dòng)修正某些錯(cuò)誤,磁盤上的文件會(huì)被一個(gè)修正后的版本覆蓋。 - 請(qǐng)確保在對(duì)文件執(zhí)行
swiftlint autocorrect之前有對(duì)它們做過備份,否則的話有可能導(dǎo)致重要數(shù)據(jù)的丟失。 - 因?yàn)樵趫?zhí)行自動(dòng)更正修改某個(gè)文件后很有可能導(dǎo)致之前生成的代碼檢查信息無效或者不正確,所以當(dāng)在執(zhí)行代碼更正時(shí)標(biāo)準(zhǔn)的檢查是無法使用的。
五. 最后貼上官方示例
disabled_rules: # 執(zhí)行時(shí)排除掉的規(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` 會(huì)被忽略。
- Source
excluded: # 執(zhí)行 linting 時(shí)忽略的路徑。 優(yōu)先級(jí)比 `included` 更高。
- Carthage
- Pods
- Source/ExcludedFolder
- Source/ExcludedFile.swift
# 可配置的規(guī)則可以通過這個(gè)配置文件來自定義
# 二進(jìn)制規(guī)則可以設(shè)置他們的嚴(yán)格程度
force_cast: warning # 隱式
force_try:
severity: warning # 顯式
# 同時(shí)有警告和錯(cuò)誤等級(jí)的規(guī)則,可以只設(shè)置它的警告等級(jí)
# 隱式
line_length: 110
# 可以通過一個(gè)數(shù)組同時(shí)進(jìn)行隱式設(shè)置
type_body_length:
- 300 # warning
- 400 # error
# 或者也可以同時(shí)進(jìn)行顯式設(shè)置
file_length:
warning: 500
error: 1200
# 命名規(guī)則可以設(shè)置最小長(zhǎng)度和最大程度的警告/錯(cuò)誤
# 此外它們也可以設(shè)置排除在外的名字
type_name:
min_length: 4 # 只是警告
max_length: # 警告和錯(cuò)誤
warning: 40
error: 50
excluded: iPhone # 排除某個(gè)名字
variable_name:
min_length: # 只有最小長(zhǎng)度
error: 4 # 只有錯(cuò)誤
excluded: # 排除某些名字
- id
- URL
- GlobalAPIKey
reporter: "xcode" # 報(bào)告類型 (xcode, json, csv, checkstyle)
附錄:
原文鏈接:https://github.com/realm/SwiftLint/blob/master/README.md
譯文鏈接:https://github.com/realm/SwiftLint/blob/master/README_CN.md