Xcode代码规范之SwiftLint配置

Xcode代码规范之SwiftLint配置

前言

  • 最近公司大佬考虑将项目代码规范化, 然而自Xcode9之后,Xcode的插件基本处于废弃的状态大部分插件都是在一年前就停止更新了;
  • 于是在谷歌找到了一款强大的代码规范工具SwiftLint
  • SwiftLintRealm 推出的一款 Swift 代码规范检查工具, SwiftLint 基于 Github 公布的 Swift 代码规范进行代码检查,并且能够很好的和 Xcode 整合
  • Github 公布的 Swift 代码规范--原文
  • Github 公布的 Swift 代码规范--中文
  • 配置好所有的设置之后,在 Xcode 中执行编译时,SwiftLint 会自动运行检查,不符合规范的代码会通过警告或者 红色错误 的形式指示出来
  • 支持自定义规则,可禁用或者开启某一些规则

一. 安装SwiftLint

  • SwiftLint目前有三种安装方式可供选择,可以根据自己的项目需要自行选择

1. 安装全局配置(Homebrew 安装)

Homebrew

  • Homebrew, Mac系统的包管理器,用于安装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目录不可写的权限问题。可以使用下面的命令修复:

sudo chown -R `whoami` /usr/local
  • Homebrew 会自动安装最新版本
  • 打开终端输入以下代码:
brew install swiftlint

安装成功,如下图所示:

Homebrew 安装

2. 使用 CocoaPods 安装

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

3. 使用安装包

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

二. 查看SwiftLint的全部命令

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

各个命令注释

//查看所有命令
swiftlint help

//忽略空格导致的警告和错误
swiftlint autocorrect

//输出所有的警告和错误
swiftlint lint

//查看所有可获得的规则以及对应的 ID
swiftlint rules

//产看当前版本号
swiftlint version
  • 我们将目录切换到工程的根目录之下,然后敲击如下命令:
swiftlint autocorrect

然后我们就会发现,所有的空格符Warning都消失了。这都得益于我们刚刚所进行的命令行操作,它会将已知的能够自动修复的Error和Warning都自动修复,大大的减轻了我们的工作量。

三. SwiftLint的使用

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

  • 配置代码添加步骤
  • 需要将相关脚本添加到红色框内
配置代码添加步骤

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"
  • 这里其实是设置了一个自动编译脚本,每次运行编译都会自动执行这个脚本
  • 如果正确安装了 SwiftLint,就会执行 SwiftLint 中的代码规范检查,如果没有安装,脚本会抛出一个没有安装 SwiftLint 并提示下载的警告,方便提醒团队团队中没有安装的成员。
  • 当然,你也可以设置为强制要求安装,这时如果没有安装则无法通过编译。只需要在脚本中
echo "warning: ..."

之后添加一行代码:

exit 1
  • 这样一来,如果没有安装 SwiftLint,编译时会直接抛出一个编译错误而非警告,提示需要安装 SwiftLint。

3. 配置完成后,command+B编译

  • 如果你的是正在开发中的项目, 你可能会发现你的项目提示999+的黄色警告和999+的红色错误
  • 甚至你会发现甚至一些空格和一些系统的方法和注释也会报错或者警告
  • SwiftLint默认方法名或者注释不得超过120个字符
测试项目
  • Swift Lint 在完成上述操作之后,便已经生效。但是,如果觉得默认的风格过于严格,或者项目组有另外的要求,Swift Lint 也可以定制相应的风格,或者禁用某些规则。
  • SwiftLint 的全部规则可以在:Source/SwiftLintFramework/Rules 目录内找到

四. 自定义配置

  • 当你编译过项目后,看到999+的警告和错误,是不是第一反应就是要放弃了,其实不然
  • 仔细看一下具体的错误,会发现好多都是第三方库的代码规范问题,而且好多问题的级别被设置成为了 error
  • 第三方库的代码规范问题,这个锅我们可不能背
  • 这里我们可以做一些配置,让 SwiftLint 在做代码规范检查的时候自动忽略 CocoaPodsCarthage 等包管理器引入的第三方库(当然,手动导入的第三方库也能设置忽略)

1. 创建配置文件

  • 首先需要在项目的根目录下新建一个名为 .swiftlint.yml 的配置文件
  • 打开终端, cd 到项目根目录下
  • 输入: touch .swiftlint.yml
  • 执行完该命令后, 在文件夹中你可能找不到该yml格式文件,那是因为文件被隐藏了
  • 关于隐藏/显示隐藏文件(命令一样): command + shift + .
  • 下面我们来认识一下主要的几个配置选项
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>

例如:

    // 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)
        }
    }

规则关闭之前

Snip20180207_1.png

规则关闭之后


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

3. 忽略引入的第三方库

  • 1). 忽略CocoaPods导入的第三方库
excluded: 
  - Pods
  • 2). excluded 配置项用来设置忽略代码规范检查的路径,可以指定整个文件夹
  • 比如如果你的项目使用 Carthage 管理第三方库的话,可以将 Carthage 目录添加到忽略列表:
excluded: 
  - Pods
  - Carthage
  • 3). 指定精确路径下的文件,通过 - xxxx 的形式列在下面就可以了
excluded: # 执行 linting 时忽略的路径。 优先级比 `included` 更高。
  - Source/ExcludedFolder
  - Source/ExcludedFile.swift

4. 嵌套配置

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

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

5. 自动更正

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

五. 最后贴上官方示例

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

# 可配置的规则可以通过这个配置文件来自定义
# 二进制规则可以设置他们的严格程度
force_cast: warning # 隐式
force_try:
  severity: warning # 显式
# 同时有警告和错误等级的规则,可以只设置它的警告等级
# 隐式
line_length: 110
# 可以通过一个数组同时进行隐式设置
type_body_length:
  - 300 # warning
  - 400 # error
# 或者也可以同时进行显式设置
file_length:
  warning: 500
  error: 1200
# 命名规则可以设置最小长度和最大程度的警告/错误
# 此外它们也可以设置排除在外的名字
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

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

推荐阅读更多精彩内容