CodeReview之SwiftLint

一、前言

  • SwiftLintRealm 推出的一款 Swift 代码规范检查工具,SwiftLint 是基于 GitHub 公布的 Swift代码规范 对 Swift 代码进行检查的。
  • GitHub 公布的 Swift 代码规范 - 原文
  • GitHub 公布的 Swift 代码规范 - 中文
  • 配置好 SwiftLint 之后,在 Xcode 中直接编译代码,SwiftLint 就会按照预先设置好的代码规范自动检查代码,不符合规范的代码就会通过警告(warning)或者报错(error)的形式指示给开发者,从而对开发者的代码进行规范。
  • 除了 SwiftLint 自带的规则之外,开发者还可以自定义规则。同时可以禁用或启用某一些规则。

二、安装 SwiftLint

SwiftLint 可以通过 3 种方式进行安装:

  • 通过 HomeBrew 安装
  • 通过 CocoaPods 安装
  • 通过 pkg 安装包安装

1、通过 Homebrew 安装【全局安装】

  • 第一步: 安装 Homebrew (如已安装,请跳过)
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

如果出现下图所示,表示 Homebrew 安装成功。

Homebrew安装成功.png
  • 第二步: 通过终端命令安装 SwiftLint
brew install SwiftLint
SwiftLint 安装成功.png

2、通过 CocoaPods 安装【局部安装】

  • 通过 CocoaPods 安装,只对单个项目有效,如果想要对不同的项目使用不同的 SwiftLint 版本,这会是一种很好的解决方案。
  • 需要注意的是使用这种方案会将整个 SwiftLint 以及它的依赖包的完整资源文件都安装到 Pods/ 目录中去,所以在使用代码版本管理工具比如 git/svn 时要注意设置忽略(ignore)相关目录。
  • 通过 CocoaPods 安装 SwiftLint,跟安装第三方框架一样。
  • 在项目根目录创建 Podfile
pod 'SwiftLint'

3、通过安装包安装【全局安装】

SwiftLint 还支持使用 pkg 安装包进行安装,在官方的 GitHub 页面可以找到最新发布的安装包

SwiftLint 安装包.png

三、查看 SwiftLint 的全部命令

  • 在终端中输入 swiftlint help
swiftlint help
SwiftLint 的全部命令.png
  • 各个命令注释:
# Automatically correct warnings and errors
# 自动更改警告和错误(仅适用于支持自动更改的规则)
autocorrect     

# Generates markdown documentation for all rules
# 为所有规则生成 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    
# 显示所有规则的列表以及对应的 ID   
rules      
  
# Display the current version of SwiftLint   
# 显示 SwiftLint 的当前版本号
version         

四、SwiftLint 的使用

安装完成之后,需要在Xcode中配置相关设置,才能使 SwiftLint 在 Xcode 中自动检测代码规范。配置也很简单,只需要在 Xcode 的 Build Phases 中新建一个 Run Script Phase 配置项,在里面添加相关代码后,编译即可!

1、SwiftLint 脚本设置

  • 这里分两种情况: 全局脚本的添加 和 局部脚本的添加。

(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
  • 这里其实是设置了一个自动编译脚本,每次运行编译都会自动执行这个脚本。
  • 如果正确安装了 SwiftLint,就会执行 SwiftLint 中的代码规范检查,如果没有安装,脚本会抛出一个没有安装 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
  • 如图,新建项目,任何代码都没写,直接报出一堆 警告,甚至还有 错误。试想,如果是正在开发中的项目,你可能会发现你的项目提示N+的黄色警告和N+的红色错误。
  • 通过 SwiftLintDemo,你会发现甚至一些空格和一些系统的方法和注释也会报错或者警告。
  • SwiftLint 默认方法名或者注释不得超过120个字符。
  • SwiftLint 的所有规则可以在: Rules 找到。

五、自定义配置

  • 当我们编译一个正在开发的项目代码后,看到的 N 多的警告和错误,其实并不全都需要我们来解决,因为这里面通常包含了第三方库的代码规范问题,而且好多问题的级别都被设置成了 error
  • 第三方库的代码规范问题,这不是我们的问题,怎么解决
  • 因此,我们需要做一些设置,让 SwiftLint 在做代码规范检查的时候自动忽略 CocoaPodsCarthage 等包管理器引入的第三方库(当然,手动导入的第三方库也能设置忽略)。
  • 上面的问题需要我们来 自定义配置文件

1、创建配置文件

  • 首先,需要在项目的根目录下新建一个名为 .swiftlint.yml 的配置文件。

  • 打开终端,cd 进入项目根目录下。

  • 输入: touch .swiftlint.yml

    创建 .swiftlint.yml文件.png

  • 执行完命令之后,在文件夹中就会有一个 .swiftlint.yml 的隐藏文件。

  • 隐藏/显示隐藏文件的命令: Command + Shift + .

    隐藏的配置文件.png

  • 下面来认识一下主要的几个配置选项

disabled_rules: # 禁用指定的规则
  - colon
  - comma
  - control_statement
opt_in_rules: # 启用指定的规则
  - empty_count
  - missing_docs
  # 可以通过执行如下指令来查找所有可用的规则:
  # swiftlint rules
included: # 执行 linting 时包含的路径。如果出现这个 `--path` 会被忽略。
  - Source
excluded: # 执行 linting 时忽略的路径。 优先级比 `included` 更高。
  - Carthage
  - Pods
  - Source/ExcludedFolder
  - Source/ExcludedFile.swift

2、在代码中关闭某个规则

  • 可以通过在一个源文件中定义一个如下格式的注释来关闭这个规则
// swiftlint:disable <rule>
  • 在该文件结束之前或者在定义如下格式的匹配注释之前,这条规则都会被禁用:
// 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.
    }

规则关闭之前:

规则关闭之前.png

规则关闭之后:

规则关闭之后.png
  • 也可以通过添加 :previous, :this 或者 :next 来使关闭或者打开某条规则的命令分别应用于前一行,当前或者后一行代码。
// 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

规则关闭之前:

规则关闭之前.png

规则关闭之后:

规则关闭之后.png

3、忽略引入的第三方库

excluded 配置选项用来设置忽略代码规范检查的路径,可以指定整个文件夹。

  • 忽略 CocoaPods 引入的第三方库
excluded: 
  - Pods
  • 如果你的项目中使用 Carthage 管理第三方库,可以将 Carthage 目录添加到忽略列表:
excluded:
  - Pods
  - Carthage
  • 指定精确路径下的文件,通过 - xxx 的形式列在下面就可以了。
excluded: # 执行 linting 时忽略的路径。优先级比 `included` 更高。
  - Source/ExcludedFolder
  - Source/ExcludedFile.swift

4、嵌套配置

SwiftLint 支持通过嵌套配置文件的方式来对代码分析过程进行更加细致的控制。

  • 在项目的 根 .swiftlint.yml 文件里设置 user_nested_configs: true 值。
  • 在目录结构必要的地方引入额外的 .swiftlint.yml 文件。
  • 每个文件被检查时会使用在文件所在目录下的或者父目录的更深层目录下的配置文件。否则根配置文件将会生效。
  • excludedincludeduse_nested_configs 在嵌套结构中会被忽略。

5、自动更正

  • Swiftlint 可以自动修正某些错误,磁盘上的文件会被一个修正后的版本覆盖。
  • 请确保在对文件执行 swiftlint autocorrect 之前有对它们做过备份,否则的话有可能导致重要数据的丢失。
  • 因为在执行自动更正修改某个文件后,很有可能导致之前生成的代码检查信息无效或者不正确,所以当在执行代码更正时标准的检查是无法使用的。

官方示例

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)

最后

原文链接
译文链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明先生_X自主阅读 15,979评论 3 119
  • 我们常常说,在大学面临选择的时候,父母为你铺的路,不一定是你最想要的。长辈们给的建议,不一定是你最心之神往的。所有...
    家以纯阅读 273评论 0 8
  • 梦境是冥冥之中的注定。如果不写下来就会忘记,不管梦里的事物有多么真实;不管梦里的你爱的多么深。 初次看到《你的名字...
    Marssi阅读 895评论 0 1
  • 中性笔+油画棒 下班后和朋友逛街。 本没打算买包,偏偏那家店要开在下班必经路上。 进,看,买,走,十分钟不到。 原...
    巫落阅读 173评论 0 0