美文网首页SwiftiOS 实用技术iOS-swift
SwiftLint,规范代码,成为完美的偏执患者

SwiftLint,规范代码,成为完美的偏执患者

作者: Maru | 来源:发表于2017-05-18 18:18 被阅读1829次

    (一)什么是SwiftLint ?

    SwiftLint.jpg

    熟悉Python的同学一定对Pylint不会陌生,Pylint 是一个 Python 代码分析工具,它分析 Python 代码中的错误,查找不符合代码风格标准(Pylint 默认使用的代码风格是 PEP 8,具体信息,请参阅参考资料)和有潜在问题的代码。Python是一门很强调格式的语言,毕竟人家连大括号都没有,反观Swift,似乎不按照严格的规范编码也没有太大的问题?错!写出良好代码风格的代码,可能比能否写出高效的代码更为重要。于是,SwiftLint就诞生了。SwiftLint是一个强制使用者按照Github的Swift编码规范指南来开发的一种工具,它会将所有不符合Swift规范的代码全部用warning标注出来,一些严重的违背规则的代码甚至让它无法通过编译(江山一片红),想想是不是就很刺激呢?

    (二)为什么需要Lint ?

    1.独行侠的困局

    如果你是个人开发,或者说团队没有CodeReview,那么你的代码绝对不是“完美”的。人总是会犯错的,尤其是在高速的迭代和业务需求快速变更的时候,犯错的几率会成倍的增加。最让人尴尬的是,Xcode是非常包容的,即使你的代码不符合规范,但是如果语法是没有问题的,那么它也会特别乐意的让你通过编译并且没有任何的警告。

    但是,但凡你是一个有追求的开发者,都会希望自己所写出来的代码,至少在代码风格上面无可挑剔。但是这又和现实世界的开发需求以及人性相矛盾,所以这就是一个困局。

    2.CodeReview之殇

    有幸,你所处在的公司是一个有技术追求的公司。那么,你们一定会有大量的互相Review。在我看来,CodeReview一般做这样几件事情:

    • 代码风格规范统一
    • 防止低效代码、冗余代码
    • 防止出现可见的明显BUG

    第二第三点,其中富含了大量人脑的思考,属于暂时还无法替代的操作(AI时代应该可以)。但是第一点,实在属于机械操作,就好像第一次工业革命的人工织布,是处在必然被淘汰的行列。

    在这样的时代浪潮之下,SwiftLint 应运而生。

    (三) 安装

    没有办法,按照技术文章的三板斧:安装 - 使用 - 踩坑,这是怎么也绕不过去的一章。我相信读者都聪慧无比,但是为了文章的完整性我还是要啰嗦几句。

    (1) 全局安装

    全局安装就不得不提到我们的老朋友HomeBrew了,如果你没有安装,那么请看这里

    全局安装非常简单,首先我们需要通过brew命令安装SwiftLint:

    brew install swiftlint
    

    然后添加编译脚本:

    全局安装步骤图.png

    最后在黑框框中添加如下脚本:

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

    Script.png

    OK,大功告成,就可以编译啦,之后每次安装只需要给工程添加脚本就可以了。

    (2) 局部安装

    除了全局安装,我们也可以通过CocoaPods进行安装。在Podfile上添加相关的依赖:

    pod 'SwiftLint'
    

    然后跟全局方法一样,在Run Script中添加命令,但是内容有些许的不同:

    "${PODS_ROOT}/SwiftLint/swiftlint"
    
    局部安装.png

    OK,接下来就让我们来试试看SwiftLint吧!

    (三)使用

    在给项目初次接入SwiftLint的时候,你可能会被下面这样的情景给吓到:

    疯狂Warning和Error.png

    但是呢,不用慌,我们可以看一下这是什么情况。仔细观察一番之后,我们会发现,绝大多数的Warning都是这个原因:

    image.png

    WTF?我这一行哪里有空格符?简直就是冤枉啊!但其实是这样的,虽然看起来好像没有空格符,但是在换行符之间不应该掺杂制表符,也就是说你实际的代码是这样的:

    \n \tab \n
    

    所以呢,人家的Warning也不是没有道理的嘛。那么我们该怎么来消除这些Warning呢?

    首先,我们要确保,以后我们所码的代码不再出现这样的格式,所以我们需要把Text Editing里面的Including whitespace-only lines勾选上:

    image.png

    这样可以保证我们今后的换行不再出现制表符的警告,然后,我们就需要处理现有的代码。现有的代码,少说也有几万行,手动改不是要累死人?这个时候就轮到SwiftLint的命令行出场了:

    image.png

    我们将目录切换到工程的根目录之下,然后敲击如下命令:

    swiftlint autocorrect
    

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

    但是又出现了一个问题,在项目的根目录之下执行自动纠正,SwiftLint会将Pods文件夹中的Swift文件也一起纠正了,第三方的框架原则上能不动就不动,那么我们该怎么办呢?

    这个时候就需要.swiftlint.yml文件了。那么这是一个什么文件呢?在使用SwiftLint的时候,很多时候我们会碰到一些自定义的规则需求,这个时候就需要.swiftlint.yml来解决问题了。

    .swiftlint.yml

    所谓的.swiftlint.yml其实就是SwiftLint的一个配置文件,我们可以通过这个配置文件来修改约束的规则,以此达到自定义的效果。

    一般的配置文件大概长这个样子:

    image.png

    下面我们来认识一下主要的几个配置选项,在此之前我们先要了解一下SwiftLint中的一个概念rules,所谓的rules就是一个一个的风格规则,比如冒号的规则,空格符的规则,类型名的规则等等。截止目前,SwiftLint一共支持75种规则,如果你感兴趣,可以在Source/SwiftLintFramework/Rules 中看到所有规则的实现。或者你也可以在终端输入swiftlint rules来查看当前的规则信息。

    disabled_rules

    disabled_rules: # 禁用指定的规则
      - file_length
      - ...
    

    opt_in_rules

    opt_in_rules: # 启用指定的规则
      - file_length
      - ...
    

    whitelist_rules

    whitelist_rules: # 规则的白名单,但是不能和上面两个规则一起使用
      - file_length 
      - ...
    

    included

    included: # 你所希望Lint检索的路径,SwiftLint会扫描该路径下的所有.swift后缀的文件
      - ../
    

    excluded

    excluded: # 你所希望不要检索的路径,SwiftLint会无视掉该路径下的文件
      - Pods
    

    风格规则

    由于风格规则太多了,这里不一一列举,但是用法都是大致相同的:

    force_cast: [warning | error] 当出现强制类型转换的时候是提示Error还是Warning
    
    type_body_length:
      - 300 # 当超过300行的时候飚黄
      - 400 # 当超过400行的时候飚红
    

    ** 还有很多的规则,用法大致相同,读者如此聪慧,老夫不必多言。 **

    注释控制

    还有一个场景,有的时候,我们并不想大范围的禁用掉一个规则,但是在某个文件中,我们必须要无视这条规则,那么我们应该怎么告诉SwiftLint来无视掉它呢?

    ** 很简单,注释!**

    比如以下这种情况:

    image.png

    哇,这个是系统给的代理方法啊,竟然还警告我方法名称过长!难道无视他?不行,强迫症患者忍受不了啊!

    于是我们可以这样:

    image.png

    OK,这样在// swiftlint:disable line_length注释之后的所有行长的警告都会被忽略掉。如果你想要在忽略掉这一行之后再次启用,那么只要再添加一行// swiftlint:enable line_length就可以了。

    image.png

    如果你觉得,有很多的控制注释也看起来不顺眼的话,个人推荐可以这样,把它写在开头的注释上:

    image.png

    或者更加的极端:

    image.png

    配置文件的嵌套

    值得一提的是,在我们使用配置文件的时候,SwiftLint会默认将所指定的文件目录递归的扫描下去的。如果扫描过程中,在子目录下发现了一个新的.swiftlint.yml文件,那么子目录下的规则就会改为新的配置规则。听起来很实用,但是本人还没用过💔。

    (四)踩坑

    在本人使用该Lint的这段时间中,发现有两个使用麻烦的地方,分享出来。

    一号建议

    注释控制在实际的使用中非常的常用,所以强烈建议使用代码块来简化操作:

    image.png

    二号建议

    在实际的使用中,.swiftlint.yml的创建也是非常频繁的,尤其是如果你是通过模块化的开发,那么每当新建一个模块或者给一个模块添加Lint的时候,你就需要创建至少一个YML文件,所以个人建议可以给SwiftLint添加一个辅助的命令行。

    我使用Swift简单实现了一个Maker,将其编译之后的二进制可执行文件拷贝到/usr/local/bin之后就可以使用了。

    image.png

    之后我们通过下面的命令就可以快速的创建一个YML文件,我们只需要在模板文件的基础上进行修改就可以了:

    maker -y
    
    image.png image.png

    编译方法

    有同学说,不知道怎么使用Maker,这里简单介绍一下,其实发布APP类似:

    1.Xcode编译方案

    首先我们打开Maker工程,然后点击Archive(签名的事情自己搞定啊):

    image.png

    稍等片刻,我们的程序就编译完成了,然后步骤如下:

    image.png image.png image.png image.png

    最后只需要两句命令:

    image.png
    2.命令行编译方案

    第二种方法直接通过纯命令的方式,更加简单:

    cd path # 这里的path是指main.swift所在的文件目录之下
    swiftc main.swift Maker.swift -o Maker # 编译生成二进制文件
    cp Maker /usr/local/bin # 复制到目标目录之下
    

    OK! 大功告成! 快试试Maker吧!

    这样对我这种记性不太好的人来说就友好了许多o( ̄▽ ̄)d,其实讲道理应该发布HomeBrew之类的地方更加方便,但是功能太简单不好意思,就随便搞了搞,以后加了其他功能可能会考虑。

    顺便说一嘴,在Xcode插件被禁用之后,很多好用的功能都离我们远去了,但是这并不是意味着工作效率的降低。比如上述的命令行工具,更多的旨在抛砖引玉,主旨都是为了加快我们的开发效率,所以不要再只把Swift当做iOS开发语言了哦!

    Ending

    由此可见,SwiftLint 使用起来对于开发者也是比较有好的。但凡是一个有代码洁癖的iOS程序员,都可以来试试这个SwiftLint,我相信你绝对不会后悔了。在漫长的求职路上,我希望你不要因为代码风格问题被面试刷掉。

    最后的最后,祝愿世界上所有的代码都能如诗般优雅整洁😂。

    相关文章

      网友评论

      • 不必luo嗦:你好,我想问下 除了你这个创建.yml的方法,还有什么方法或者工具创建.yml文件。谢谢
        Maru:@丶Destinyxl 或者依靠CI系统自动创建,这样公司不同的项目可以共享一套yml规则
        丶Destinyxl:同求一下
      • midmirror:绝对不用这鬼东西。代码的规范靠的是自己的约束。用了这鬼东西反而是给自己效率上找麻烦。
        不是谢志伟:人总会犯错。这种东西只需要设置一次, 后面带来的价值是很大的。特别对于团队来说, 你能保证所有人的代码都规范吗:)
        Maru:@midmirror 自己约束总会有疏漏
      • 一把辛酸泪__:`swiftlint autocorrect` 这个命令需要安装`SwiftLintXcode`插件吧
        一把辛酸泪__:@Maru恩,试过,可以:blush:
        Maru:@醉江月 不需要,安装cli就行
      • xiAo__Ju:我是配合SwiftFormat用
      • 半杯故事:请问下编译后的二进制文件在哪看
        半杯故事:@Maru 谢谢分享,已经可以了
        Maru:我更新了一下文章,你可以看一下编译方式

      本文标题:SwiftLint,规范代码,成为完美的偏执患者

      本文链接:https://www.haomeiwen.com/subject/mjgstxtx.html