使用 SwiftLint 進(jìn)行 Swift 代碼規(guī)范檢查

所有文章已搬遷到個(gè)人站點(diǎn):me.harley-xk.studio憎蛤,歡迎訪問留言

原由

最近跟著公司大佬在做 Laravel 后端開發(fā)果善,要求使用 php lint 進(jìn)行代碼規(guī)范檢查之后才能 push 代碼踪旷,保證所有人寫出風(fēng)格統(tǒng)一的代碼逞盆,方便后期的維護(hù)和 Review刊懈,于是開始往老本行上反思绿饵。
想想自己寫了五六年的 iOS 刀森,雖然自認(rèn)代碼還是寫的很規(guī)整的踱启,但是寫 high 了之后還是會(huì)忽略很多細(xì)節(jié)上的東西,雖說無傷大雅研底,但是軟件開發(fā)作為一門工程性質(zhì)的東東埠偿,始終覺得規(guī)范化是一件很重要的事情。
在之前的公司也曾經(jīng)在 iOS 組內(nèi)部推行過代碼規(guī)范的實(shí)施榜晦,但那時(shí)候還只是停留在弄個(gè) Word 文檔冠蒋,把各條規(guī)范列一列,然后開個(gè)小會(huì)普及下的程度上∏海現(xiàn)在接觸了不少其他開發(fā)領(lǐng)域的東西抖剿,越來越覺得對(duì)于開發(fā)者來說提高視角去了解各個(gè)方面是多么重要的一件事情。不同領(lǐng)域的經(jīng)驗(yàn)识窿、做事的方式斩郎、思路,都可以相互借鑒與融合喻频。
于是開始尋找在 iOS 下實(shí)行類似方案的可能性缩宜。說來也巧,最近在看 iOS 相關(guān)資料的時(shí)候發(fā)現(xiàn)了 SwiftLint 這玩意兒,遂打算來實(shí)踐下锻煌。

SwiftLint 是啥妓布?

SwiftLintRealm 推出的一款 Swift 代碼規(guī)范檢查工具,Realm 就不用介紹了宋梧,他們家推出的移動(dòng)端跨平臺(tái)數(shù)據(jù)庫在業(yè)內(nèi)的名氣還是很大的匣沼,就算沒有用過,相信大多數(shù)人也是聽過的捂龄。
SwiftLint 基于 Github 公布的 Swift 代碼規(guī)范進(jìn)行代碼檢查释涛,并且能夠很好的和 Xcode 整合。配置好所有的設(shè)置之后倦沧,在 Xcode 中執(zhí)行編譯時(shí)枢贿,SwiftLint 會(huì)自動(dòng)運(yùn)行檢查,不符合規(guī)范的代碼會(huì)通過警告或者 error 的形式指示出來刀脏,并且擁有豐富的配置項(xiàng),可以進(jìn)行大量的自定義超凳,相當(dāng)方便愈污。

安裝配置

SwiftLint 有多種不同的安裝方式,可以根據(jù)自己的喜好選擇轮傍。

使用 Homebrew 安裝

Homebrew 是 macOS 自帶的包管理工具暂雹,使用這種方式安裝也是最簡單的:

brew install swiftlint
使用 CocoaPods 安裝

通過 CocoaPods 安裝同樣很簡單,只需要在 Podfile 中添加依賴:

pod 'SwiftLint'

之后執(zhí)行 pod install 就可以自動(dòng)安裝了创夜,這種方式會(huì)將 SwiftLint 安裝到項(xiàng)目的 Pods/ 目錄下杭跪。如果你想要針對(duì)不同的項(xiàng)目使用不同的 SwiftLint 版本,這是一種很好的解決方案(Homebrew 會(huì)自動(dòng)安裝最新版本)驰吓。

需要注意的是使用這種方案會(huì)將整個(gè) ** SwiftLint** 以及他的依賴包的完整資源文件都安裝到 Pods/ 目錄中去涧尿,所以在使用版本管理工具比如 git 時(shí)要注意設(shè)置忽略相關(guān)目錄。

使用安裝包

SwiftLint 還支持使用 pkg 安裝包進(jìn)行安裝檬贰,在官方的 Github 頁面可以找到最新發(fā)布的安裝包姑廉。

編譯源代碼

SwiftLint 完全使用 Swift 開發(fā),并且它是基于 MIT License 開源的翁涤,所以你可以下載它的源代碼桥言,然后通過以下命令編譯安裝:

git submodule update --init --recursive; make install
安裝完成

等待安裝完成,輸入 swiftlint help 可以查看所有可用的命令:

?  ~ swiftlint help
Available commands:

   autocorrect   Automatically correct warnings and errors
   help          Display general or command-specific help
   lint          Print lint warnings and errors (default command)
   rules         Display the list of rules and their identifiers
   version       Display the current version of SwiftLint

到此 SwiftLint 就安裝完成了

配置 Xcode

接下來需要在工程中配置相關(guān)編譯選項(xiàng)葵礼,才能使 SwiftLint 在 Xcode 中運(yùn)行起來号阿。配置也很簡單,只需要在 Xcode 的 Build Phases 中新建一個(gè) Run Script Phase 配置項(xiàng)鸳粉,在里面添加如下代碼:

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

如圖所示:
[圖片上傳失敗...(image-933261-1580636760609)]

如果是通過 CocoaPods 安裝的 SwiftLint 需要將 swiftlint 替換為 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稳诚。
到此配置就完成了哗脖,是不是很簡單。

自定義配置

現(xiàn)在編譯一下項(xiàng)目看看扳还,是不是很可怕??:


不要被 999+ 嚇到了才避,仔細(xì)看一下具體的錯(cuò)誤,會(huì)發(fā)現(xiàn)好多都是第三方庫的代碼規(guī)范問題氨距,而且好多問題的級(jí)別被設(shè)置成為了 error
這樣子可不行桑逝,第三方庫的代碼規(guī)范問題不能讓我們自己的項(xiàng)目來背鍋,接下來需要做一些配置俏让,讓 SwiftLint 在做代碼規(guī)范檢查的時(shí)候自動(dòng)忽略 CocoaPods楞遏、Carthage 等包管理器引入的第三方庫(當(dāng)然,手動(dòng)導(dǎo)入的第三方庫也能設(shè)置忽略)

首先需要在項(xiàng)目的根目錄下新建一個(gè)名為 .swiftlint.yml 的配置文件首昔,輸入如下內(nèi)容:

excluded: 
  - Pods

excluded 配置項(xiàng)用來設(shè)置忽略代碼規(guī)范檢查的路徑寡喝,可以指定整個(gè)文件夾,也可以指定精確路徑下的文件沙廉,通過 - xxxx 的形式列在下面就可以了拘荡,比如如果你的項(xiàng)目使用 Carthage 管理第三方庫的話,可以將 Carthage 目錄添加到忽略列表:

excluded: 
  - Pods
  - Carthage

保存之后再來編譯下撬陵,少了很多編譯錯(cuò)誤了珊皿,至少第三方庫的編譯錯(cuò)誤都被干掉了,oh yeah~


不過錯(cuò)誤和警告依然很多巨税,繼續(xù)往下看蟋定,發(fā)現(xiàn)大量的 trailing_whitespace 的警告,這個(gè)是之前寫代碼不注意留下的草添,在空行中包含了空格驶兜,雖然肉眼看不出來,但是 SwiftLint 火眼金睛啊。

你可以選擇更正所有這些不規(guī)范的問題抄淑,不過如果這個(gè)這個(gè)項(xiàng)目是遺留下來的老項(xiàng)目屠凶,可能存在大量類似的問題,手動(dòng)更正這些問題需要相當(dāng)多的精力肆资,這時(shí)候可以選擇開啟忽略這類問題矗愧,只需要在 .swiftlint.yml 文件中加入如下代碼:

disabled_rules:
  - trailing_whitespace

再次編譯,發(fā)現(xiàn) trailing_whitespace 的問題已經(jīng)不再提示了郑原,你可以用同樣的方法配置忽略特定的規(guī)則唉韭。

其他規(guī)則

Xcode自動(dòng)生成的代碼經(jīng)常包含大段的注視,我們經(jīng)常會(huì)選擇保留這些注釋犯犁。不過 SwiftLint 有一個(gè) line_length 的規(guī)則属愤,默認(rèn)是會(huì)檢查注釋的長度的,可以在 .swiftlint.yml 中設(shè)置忽略檢查注釋的長度:

line_length:
  warning: 110
  ignores_function_declarations: true
  ignores_comments: true

這段代碼設(shè)置了 line_length 的檢查規(guī)則:
warning: 110 表示單行字符數(shù)超過 110 時(shí)拋出警告酸役,你也可以設(shè)置為其他的值住诸。
ignores_function_declarations 表示是否忽略檢查函數(shù)定義的長度
ignores_comments 設(shè)置是否忽略檢查注釋的長度
當(dāng)然,你也可以在 disabled_rules 中設(shè)置忽略單行長度規(guī)則

這里有所有目前已經(jīng)實(shí)現(xiàn)了的規(guī)則涣澡。你也可以實(shí)現(xiàn)自己的規(guī)則只壳,然后給他們發(fā) Pull requests。

本文的最后附上了我自己的 .swiftlint.yml 文件暑塑,你可以在 SwiftLint官方文檔找到更多關(guān)于自定義規(guī)則的說明。

設(shè)置完所有配置之后锅必,再次編譯代碼事格,之后就可以根據(jù)錯(cuò)誤提示去更正不規(guī)范的代碼了。

.swiftlint.yml 的嵌套

.swiftlint.yml 配置文件支持嵌套搞隐,因此

  • 你可以給每個(gè)文件夾下的代碼單獨(dú)指定不同的規(guī)則設(shè)置
  • 每個(gè)文件會(huì)匹配距離自己層級(jí)最近的父文件夾中的配置文件
  • 嵌套的配置文件中的 excludedincluded 配置會(huì)被忽略
結(jié)語

終于寫完了第一篇技術(shù)博客驹愚,深感寫文章的不易,希望能保持下去劣纲。
這篇文章是我在初步研究了 SwiftLint 之后寫的逢捺,一定有很多謬誤和不足之處,各位輕噴- -


<a name="SwiftLint">.swiftlint.yml</a>

disabled_rules: # rule identifiers to exclude from running
  - force_cast
  - trailing_whitespace
  - cyclomatic_complexity
  - unused_closure_parameter
#   - colon
#   - comma
#   - control_statement
# opt_in_rules: # some rules are only opt-in
#   - empty_count
#   - missing_docs
#   # Find all the available rules by running:
#   # swiftlint rules
# included: # paths to include during linting. `--path` is ignored if present.
#   - Docs.M/*/*.swift
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:
  warning: 200
  ignores_function_declarations: true
  ignores_comments: true

# 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: 3 # only error
  excluded: # excluded via string array
    - id
#     - URL
#     - GlobalAPIKey
reporter: "xcode" # reporter type (xcode, json, csv, checkstyle, junit, html, emoji)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末癞季,一起剝皮案震驚了整個(gè)濱河市劫瞳,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌绷柒,老刑警劉巖志于,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異废睦,居然都是意外死亡伺绽,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奈应,“玉大人澜掩,你說我怎么就攤上這事≌日酰” “怎么了肩榕?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長程梦。 經(jīng)常有香客問我点把,道長,這世上最難降的妖魔是什么屿附? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任郎逃,我火速辦了婚禮,結(jié)果婚禮上挺份,老公的妹妹穿的比我還像新娘褒翰。我一直安慰自己,他們只是感情好匀泊,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布优训。 她就那樣靜靜地躺著,像睡著了一般各聘。 火紅的嫁衣襯著肌膚如雪揣非。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天躲因,我揣著相機(jī)與錄音早敬,去河邊找鬼。 笑死大脉,一個(gè)胖子當(dāng)著我的面吹牛搞监,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播镰矿,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼琐驴,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了秤标?” 一聲冷哼從身側(cè)響起绝淡,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎苍姜,沒想到半個(gè)月后够委,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡怖现,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年茁帽,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了玉罐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡潘拨,死狀恐怖吊输,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情铁追,我是刑警寧澤季蚂,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站琅束,受9級(jí)特大地震影響扭屁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜涩禀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一料滥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧艾船,春花似錦葵腹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至爷怀,卻和暖如春阻肩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背运授。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工磺浙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人徒坡。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像瘤缩,于是被迫代替她去往敵國和親喇完。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理剥啤,服務(wù)發(fā)現(xiàn)锦溪,斷路器,智...
    卡卡羅2017閱讀 134,659評(píng)論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,822評(píng)論 6 342
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,162評(píng)論 25 707
  • 有時(shí)候,我們很多人只是把自己困在一個(gè)圈子里牺丙。有的人單身则涯,只是過于閉塞复局,自己的生活過于單調(diào)平淡,雖說平淡無罪粟判,但往往...
    遺棄小屋閱讀 462評(píng)論 0 2
  • 想動(dòng)筆寫下在泰國經(jīng)歷的事亿昏,也想了很久了。每次走在路上档礁,在課室坐著角钩,家中沙發(fā)躺著,腦袋里都是文章的構(gòu)思和語句呻澜。但卻一...
    夏仇閱讀 456評(píng)論 0 1