Xcode代碼規(guī)范之SwiftLint配置

Xcode代碼規(guī)范之SwiftLint配置

前言

  • 最近公司大佬考慮將項目代碼規(guī)范化, 然而自Xcode9之后,Xcode的插件基本處于廢棄的狀態(tài)大部分插件都是在一年前就停止更新了;
  • 于是在谷歌找到了一款強大的代碼規(guī)范工具SwiftLint
  • SwiftLintRealm 推出的一款 Swift 代碼規(guī)范檢查工具, SwiftLint 基于 Github 公布的 Swift 代碼規(guī)范進行代碼檢查蹬蚁,并且能夠很好的和 Xcode 整合
  • Github 公布的 Swift 代碼規(guī)范--原文
  • Github 公布的 Swift 代碼規(guī)范--中文
  • 配置好所有的設(shè)置之后素邪,在 Xcode 中執(zhí)行編譯時蝙云,SwiftLint 會自動運行檢查,不符合規(guī)范的代碼會通過警告或者 紅色錯誤 的形式指示出來
  • 支持自定義規(guī)則,可禁用或者開啟某一些規(guī)則

一. 安裝SwiftLint

  • SwiftLint目前有三種安裝方式可供選擇,可以根據(jù)自己的項目需要自行選擇

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在安裝軟件時可能會碰到/usr/local目錄不可寫的權(quán)限問題幔嗦∧鹄ⅲ可以使用下面的命令修復(fù):

sudo chown -R `whoami` /usr/local
  • Homebrew 會自動安裝最新版本
  • 打開終端輸入以下代碼:
brew install swiftlint

安裝成功,如下圖所示:

Homebrew 安裝

2. 使用 CocoaPods 安裝

  • 這種方式只能針對單個項目有效,如果你想要針對不同的項目使用不同的SwiftLint 版本,這是一種很好的解決方案
  • 需要注意的是使用這種方案會將整個SwiftLint以及他的依賴包的完整資源文件都安裝到 Pods/ 目錄中去邀泉,所以在使用版本管理工具比如 git/svn 時要注意設(shè)置忽略相關(guān)目錄
  • CocosPods安裝和安裝第三方框架一樣
  • 在根目錄創(chuàng)建Podfile
pod 'SwiftLint'

3. 使用安裝包

SwiftLint 還支持使用 pkg 安裝包進行安裝嬉挡,在官方的 Github 頁面可以找到最新發(fā)布的安裝包

二. 查看SwiftLint的全部命令

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

各個命令注釋

//查看所有命令
swiftlint help

//忽略空格導(dǎo)致的警告和錯誤
swiftlint autocorrect

//輸出所有的警告和錯誤
swiftlint lint

//查看所有可獲得的規(guī)則以及對應(yīng)的 ID
swiftlint rules

//產(chǎn)看當前版本號
swiftlint version
  • 我們將目錄切換到工程的根目錄之下汇恤,然后敲擊如下命令:
swiftlint autocorrect

然后我們就會發(fā)現(xiàn)庞钢,所有的空格符Warning都消失了。這都得益于我們剛剛所進行的命令行操作屁置,它會將已知的能夠自動修復(fù)的Error和Warning都自動修復(fù)焊夸,大大的減輕了我們的工作量。

三. SwiftLint的使用

安裝完成后,需要在Xcode中配置相關(guān)設(shè)置,才能使 SwiftLint 在 Xcode 中自動檢測代碼規(guī)范蓝角。配置也很簡單阱穗,只需要在 Xcode 的 Build Phases 中新建一個 Run Script Phase 配置項,在里面添加相關(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è)置了一個自動編譯腳本使鹅,每次運行編譯都會自動執(zhí)行這個腳本
  • 如果正確安裝了 SwiftLint揪阶,就會執(zhí)行 SwiftLint 中的代碼規(guī)范檢查,如果沒有安裝患朱,腳本會拋出一個沒有安裝 SwiftLint 并提示下載的警告鲁僚,方便提醒團隊團隊中沒有安裝的成員。
  • 當然,你也可以設(shè)置為強制要求安裝冰沙,這時如果沒有安裝則無法通過編譯侨艾。只需要在腳本中
echo "warning: ..."

之后添加一行代碼:

exit 1
  • 這樣一來,如果沒有安裝 SwiftLint拓挥,編譯時會直接拋出一個編譯錯誤而非警告唠梨,提示需要安裝 SwiftLint。

3. 配置完成后,command+B編譯

  • 如果你的是正在開發(fā)中的項目, 你可能會發(fā)現(xiàn)你的項目提示999+的黃色警告和999+的紅色錯誤
  • 甚至你會發(fā)現(xiàn)甚至一些空格和一些系統(tǒng)的方法和注釋也會報錯或者警告
  • SwiftLint默認方法名或者注釋不得超過120個字符
測試項目
  • Swift Lint 在完成上述操作之后侥啤,便已經(jīng)生效当叭。但是,如果覺得默認的風(fēng)格過于嚴格盖灸,或者項目組有另外的要求蚁鳖,Swift Lint 也可以定制相應(yīng)的風(fēng)格,或者禁用某些規(guī)則赁炎。
  • SwiftLint 的全部規(guī)則可以在:Source/SwiftLintFramework/Rules 目錄內(nèi)找到

四. 自定義配置

  • 當你編譯過項目后,看到999+的警告和錯誤,是不是第一反應(yīng)就是要放棄了,其實不然
  • 仔細看一下具體的錯誤醉箕,會發(fā)現(xiàn)好多都是第三方庫的代碼規(guī)范問題,而且好多問題的級別被設(shè)置成為了 error
  • 第三方庫的代碼規(guī)范問題,這個鍋我們可不能背
  • 這里我們可以做一些配置甘邀,讓 SwiftLint 在做代碼規(guī)范檢查的時候自動忽略 CocoaPods琅攘、Carthage 等包管理器引入的第三方庫(當然,手動導(dǎo)入的第三方庫也能設(shè)置忽略)

1. 創(chuàng)建配置文件

  • 首先需要在項目的根目錄下新建一個名為 .swiftlint.yml 的配置文件
  • 打開終端, cd 到項目根目錄下
  • 輸入: touch .swiftlint.yml
  • 執(zhí)行完該命令后, 在文件夾中你可能找不到該yml格式文件,那是因為文件被隱藏了
  • 關(guān)于隱藏/顯示隱藏文件(命令一樣): command + shift + .
  • 下面我們來認識一下主要的幾個配置選項
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>

例如:

    // 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)閉之前

Snip20180207_1.png

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


Snip20180207_2.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

3. 忽略引入的第三方庫

  • 1). 忽略CocoaPods導(dǎo)入的第三方庫
excluded: 
  - Pods
  • 2). excluded 配置項用來設(shè)置忽略代碼規(guī)范檢查的路徑荧关,可以指定整個文件夾
  • 比如如果你的項目使用 Carthage 管理第三方庫的話,可以將 Carthage 目錄添加到忽略列表:
excluded: 
  - Pods
  - Carthage
  • 3). 指定精確路徑下的文件褂傀,通過 - xxxx 的形式列在下面就可以了
excluded: # 執(zhí)行 linting 時忽略的路徑忍啤。 優(yōu)先級比 `included` 更高。
  - Source/ExcludedFolder
  - Source/ExcludedFile.swift

4. 嵌套配置

SwiftLint 支持通過嵌套配置文件的方式來對代碼分析過程進行更加細致的控制仙辟。

  • 在你的根 .swiftlint.yml 文件里設(shè)置 use_nested_configs: true 值同波。
  • 在目錄結(jié)構(gòu)必要的地方引入額外的 .swiftlint.yml 文件。
  • 每個文件被檢查時會使用在文件所在目錄下的或者父目錄的更深層目錄下的配置文件叠国。否則根配置文件將會生效未檩。
  • excludedincluded粟焊,和 use_nested_configs 在嵌套結(jié)構(gòu)中會被忽略冤狡。

5. 自動更正

  • SwiftLint 可以自動修正某些錯誤孙蒙,磁盤上的文件會被一個修正后的版本覆蓋。
  • 請確保在對文件執(zhí)行 swiftlint autocorrect 之前有對它們做過備份悲雳,否則的話有可能導(dǎo)致重要數(shù)據(jù)的丟失挎峦。
  • 因為在執(zhí)行自動更正修改某個文件后很有可能導(dǎo)致之前生成的代碼檢查信息無效或者不正確,所以當在執(zhí)行代碼更正時標準的檢查是無法使用的怜奖。

五. 最后貼上官方示例

disabled_rules: # 執(zhí)行時排除掉的規(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

# 可配置的規(guī)則可以通過這個配置文件來自定義
# 二進制規(guī)則可以設(shè)置他們的嚴格程度
force_cast: warning # 隱式
force_try:
  severity: warning # 顯式
# 同時有警告和錯誤等級的規(guī)則掷匠,可以只設(shè)置它的警告等級
# 隱式
line_length: 110
# 可以通過一個數(shù)組同時進行隱式設(shè)置
type_body_length:
  - 300 # warning
  - 400 # error
# 或者也可以同時進行顯式設(shè)置
file_length:
  warning: 500
  error: 1200
# 命名規(guī)則可以設(shè)置最小長度和最大程度的警告/錯誤
# 此外它們也可以設(shè)置排除在外的名字
type_name:
  min_length: 4 # 只是警告
  max_length: # 警告和錯誤
    warning: 40
    error: 50
  excluded: iPhone # 排除某個名字
variable_name:
  min_length: # 只有最小長度
    error: 4 # 只有錯誤
  excluded: # 排除某些名字
    - id
    - URL
    - GlobalAPIKey
reporter: "xcode" # 報告類型 (xcode, json, csv, checkstyle)

附錄:

原文鏈接:https://github.com/realm/SwiftLint/blob/master/README.md
譯文鏈接:https://github.com/realm/SwiftLint/blob/master/README_CN.md

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末滥崩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子讹语,更是在濱河造成了極大的恐慌钙皮,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件顽决,死亡現(xiàn)場離奇詭異短条,居然都是意外死亡,警方通過查閱死者的電腦和手機才菠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門茸时,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赋访,你說我怎么就攤上這事可都。” “怎么了蚓耽?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵渠牲,是天一觀的道長。 經(jīng)常有香客問我步悠,道長签杈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任鼎兽,我火速辦了婚禮答姥,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘接奈。我一直安慰自己踢涌,他們只是感情好,可當我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布序宦。 她就那樣靜靜地躺著睁壁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上潘明,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天行剂,我揣著相機與錄音,去河邊找鬼钳降。 笑死厚宰,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的遂填。 我是一名探鬼主播铲觉,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼吓坚!你這毒婦竟也來了撵幽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤礁击,失蹤者是張志新(化名)和其女友劉穎盐杂,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哆窿,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡链烈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了挚躯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片强衡。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖秧均,靈堂內(nèi)的尸體忽然破棺而出食侮,到底是詐尸還是另有隱情,我是刑警寧澤目胡,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布锯七,位于F島的核電站,受9級特大地震影響誉己,放射性物質(zhì)發(fā)生泄漏眉尸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一巨双、第九天 我趴在偏房一處隱蔽的房頂上張望噪猾。 院中可真熱鬧,春花似錦筑累、人聲如沸袱蜡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坪蚁。三九已至奔穿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間敏晤,已是汗流浹背贱田。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留嘴脾,地道東北人男摧。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像译打,于是被迫代替她去往敵國和親耗拓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,446評論 2 348

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