OCLint在Xcode中的使用
OCLint是一个强大的静态代码分析工具,可以用来提高代码质量,查找潜在的bug,主要针对c,c++和Objective-c的静态分析,功能非常强大。
一、安装OCLint
OCLint是一个开源的项目,你可以通过下载压缩包安装,需要设置对应的环境变量,也可以使用Homebrew进行安装。
1.通过下载安装包:
从OCLint的github项目链接中下载安装包:oclint-0.13-x86_64-darwin-16.7.0.tar.gz(这是我当前的最新版本,以后读者打开可能就是更新的版本了);
下载完毕后解压,目录结构是这样的:

然后获取oclint-0.13的本地路径,例如我的是 /Users/zyw/Downloads/oclint-0.13
然后打开终端,在终端里面输入命令:
vi ~/.bash_profile

回车,进入.bash_profile的vi编辑器里面,在末尾加上
OCLINT_HOME= /Users/zyw/Downloads/oclint-0.13
export PATH=$OCLINT_HOME/bin:$PATH
其中/Users/zyw/Downloads/oclint-0.13就是上面我提到的oclint-0.13在你电脑上的本地路径,之后就是保存(按Esc,shift+:,wq),环境变量即配置完毕。
2.通过Homebrew进行安装
2.1如果电脑上未安装Homebrew,输入下面命令安装:
ruby -e "$(curl --insecure -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
安装成功会显示:Installation successful!
2.2安装xcpretty (xcpretty只是其中一种,本文只介绍这一种使用)
xcpretty是OCLint的命令执行器,安装方式:
mac终端输入:
sudo gem install -n /usr/local/bin xcpretty,
终端打印 2 gem installed,即安装成功
2.3安装OCLint
终端输入:
brew tap oclint/formulae
brew install oclint
展示以下内容即为安装成功:
oclint: Not enough positional command line arguments specified!Must specify at least 1 positional arguments: See: oclint –help
至此,OCLint的安装工作算是完成;
二、OCLint在xcode中的使用
1.建立一个工程,在新建的工程里面添加一个新的目标target,并选择Aggregate为模板.

2.输入名字:OCLint

3.创建一个script

4.写入自定义的规则脚本
下面输入一个最基本的脚本(该脚本没有做任何自定义的规则,OCLint本身有默认的规则,该脚本用途是让xcode和OCLint关):
使用OCLint与xcpretty
4.1如果没有cocoapods
source ~/.bash_profile
cd ${SRCROOT}
xcodebuild clean
xcodebuild | tee xcodebuild.log | xcpretty -r json-compilation-database -o compile_commands.json
oclint-json-compilation-database oclint_args -- -report-type xcode

4.2如果项目中使用了cocoapods
可以添加 -e Pods过滤
代码如下:
source ~/.bash_profile
cd ${SRCROOT}
xcodebuild clean
xcodebuild | tee xcodebuild.log | xcpretty -r json-compilation-database -o compile_commands.json
oclint-json-compilation-database -e Pods oclints_args -- -report-type xcode
规则如下:
source ~/.bash_profile
cd ${SRCROOT}
xcodebuild clean
xcodebuild -workspace demo.xcworkspace -scheme demo | xcpretty -r json-compilation-database --output compile_commands.json
oclint-json-compilation-database -v \
-e Pods \
-e MGLivenessDetection \
-e MGBaseKit \
-e MGIDCard \
oclint_args -- -report-type xcode \
-disable-rule ObjCAssignIvarOutsideAccessors \
-disable-rule ShortVariableName \
-rc=MINIMUM_CASES_IN_SWITCH=3 \
-rc=CYCLOMATIC_COMPLEXITY=10 \
-rc=LONG_CLASS=700 \
-rc=LONG_LINE=200 \
-rc=NCSS_METHOD=40 \
-rc=NESTED_BLOCK_DEPTH=5 \
-rc=TOO_MANY_FIELDS=20 \
-rc=TOO_MANY_METHODS=30 \
-rc=TOO_MANY_PARAMETERS=6
exit
知识拓展:
这是一段结合shell的脚本语言xcodebuild | tee xcodebuild.log | xcpretty -r json-compilation-database -o >compile_commands.json
这段脚本执行会在项目的根目录生成一个xcodebuild.log和compile_commands.json文件
xcodebuild.log会记录你编译过程中的信息,如编译错误信息等;compile_commands.json文件则是记录了自定义规则代码不匹配的信息,里面是一个个字典,字典有三个键值对,command,file,directionary
oclint-json-compilation-database oclint_args -- -report-type xcode
这段脚本是把compile_commands.json里面的内容解析然后显示的xcode上面,所以xcode上面会根据这个文件显示出警告
1517385349152.jpg
5、随便写一个方法用来测试
-(NSString *)getValueForKey:(NSString *)key
{
NSData *valueData = nil;
if(valueData != nil)
{
NSString *value = [[NSString alloc] initWithData:valueData encoding:NSUTF8StringEncoding];
return value;
}
else
{
return nil;
}
}

6、运行
按command+B编译成功,会看到编译警告,如图:

7、报错
7.1如果报这个错误:
tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance
在终端中输入这个脚本:
sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer/
/Applications/Xcode.app/Contents/Developer/是我电脑的路径,换成你自己的即可
7.2如果是这个错误:
oclint: error: violations exceed threshold
P1=0[0] P2=1637[10] P3=53904[20]
修改脚本如下:
source ~/.bash_profile
cd ${SRCROOT}
xcodebuild clean
xcodebuild | tee xcodebuild.log | xcpretty -r json-compilation-database -o compile_commands.json
oclint-json-compilation-database -e Pods oclints_args -- -report-type xcode -max-priority-1=9999 -max-priority-2=9999 -max-priority-3=9999
末尾加上 -max-priority-1=9999 -max-priority-2=9999 -max-priority-3=9999
7.3出现出现了code sign错误
第一种方法:在xcodebuild后面加上参数 CODE_SIGN_IDENTITY就行了。
第二种方法,找到项目所在target,选择一个证书即可
7.4xcodebuild和xcpretty编译报错:

在终端上打印编码格式
locale

在Edit Scheme下面添加环境变量:

如图:name添加LC_ALL
Value添加zh_CN.UTF-8
8、其他原因
以上的都配置过了,xcode还是会报错,例如compile_commands.json不存在,或者编译显示success了,但是xcode仍然报红不消失(这是因为xcode对脚本的支持不够全面,中间产生的某些文件没有生成)
我的解决方案:在桌面上创建一个文件夹,取名为shell,打开终端,然后cd ./user/DeskTop/shell(这个shell文件夹的路径,直接拖到终端就会生成路径),vi xcode.sh,终端会进入到vi编辑器里面;同时会在shell文件夹里面生成一个xcode.sh文件,把xcode里面那段脚本
source ~/.bash_profile
cd ${SRCROOT}
xcodebuild clean
xcodebuild | tee xcodebuild.log | xcpretty -r json-compilation-database -o compile_commands.json
oclint-json-compilation-database oclint_args -- -report-type xcode
粘贴到刚才终端的vi编辑器里面
同时把cd ${SRCROOT}改为 cd /Users/zyw/Desktop/OCLint-Demo
/Users/zyw/Desktop/OCLint-Demo为我xcode工程的根目录,换成你的根目录即可
,之后保存退出(esc shift+: wq),终端运行刚才的文件
./xcode.sh
可能会报权限不够,这时候需要加上
chmod +x ./xcode.sh
然后在运行
./xcode.sh
下面就是清理xcode工程,多编译几次就OK了
三、OCLint的规则
OCLint默认有71条规则,查看OCLint规则索引
可以在xocde的脚本里面写代码过滤不想要的规则
下面可以看官方给的第一个规则,点击查看地址
1.BitwiseOperatorInConditional:条件运算符中的位运算符
意思:检查条件中的按位运算。虽然在一些罕见的情况下有意编写,但按位操作被认为太“聪明”了。智能代码不容易理解。
此规则由以下类定义:oclint-rules / rules / basic / BitwiseOperatorInConditionalRule.cpp

代码放入我们的工程中,command+B出现警告

修改为如下即可

2. BrokenNilCheck:破零检查
在某些情况下,Objective-C中的无效检查返回正好相反的结果。
该规则由以下类定义:oclint-rules / rules / basic / BrokenNullCheckRule.cpp

代码放入我们的工程中,command+B出现警告

修改为如下即可

其他的规则可以一个一个运行看看
四、如何在xcode中忽略某条规则
1、把在xcode中写的这句脚本
oclint-json-compilation-database oclint_args -- -report-type xcode
改为
oclint-json-compilation-database oclint_args "disable-rule=LONG_CLASS -rc LONG_VARIABLE_NAME=1200" -- -report-type xcode
双引号里面的disable-rule便是忽略某条规则,后面写上对应规则的阀值,多条的话可以在后面拼接
如:
"-disable-rule=UnusedMethodParameter -disable-rule=LongLine -disable-rule=LongMethod -disable-rule=NcssMethodCount -disable-rule=ObjCObjectSubscripting -disable-rule=LongClass -disable-rule=NcssMethodCount -disable-rule=NPathComplexity -disable-rule=NPathComplexity -rc LONG_VARIABLE_NAME=1200"
2、阀值是什么
上面的规则索引文档中


规则的下方会有该规则的阀值
(基本规则没有阀值)
最后
这些规则是有c++编写,大家想研究下可以看源码
目录如下:
├── README.md
├── oclint-core
├── oclint-driver
├── oclint-metrics
├── oclint-reporters
├── oclint-rules
└── oclint-scripts
oclint-rules/rules/basic/里面便是c++源码