iOS静态代码扫描工具Fauxpas的使用小记

Faux Pas是一个Xcode辅助工具,用以检查Xcode项目,找出常见的错误、隐藏的bug、不良实践以及可维护性问题和风格问题。 拥有可视化界面和命令行两种操作方式。

命令行的使用

基本格式

1
Fauxpas [选项] <命令>

命令列表

check <.xcodeproj文件的路径> : 检查指定的Xcode项目
check-xcode : 检查当前的xcode项目,这个命令必须运行在Xcode项目的run script里,run script中写法示例:

1
2
3
4
5
6
7
[[ ${FAUXPAS_SKIP} == 1 ]] && exit 0
FAUXPAS_PATH="/usr/local/bin/fauxpas"
if [[ -f "${FAUXPAS_PATH}" ]]; then
"${FAUXPAS_PATH}" check-xcode
else
echo "warning: Faux Pas was not found at '${FAUXPAS_PATH}'"
fi

rules <可选规则的名称> : 显示规则的详情

tags <可选标签的名称> : 显示标签的详情

exampleconfig : 输出一个配置文件的例子

validateconfig <配置文件的路径> : 验证该配置文件是否有效

clearcaches <.xcodeproj文件的路径> : 清理该项目中所有Faxu Pas的缓存

updatelicense <证书类型> <证书名称> <证书key> : 更新授权

1
2
证书类型(四种):
personal, organization-seat, site, enterprise

help : 显示完成使用信息

docs : 显示文档

version : 显示app版本号

选项列表(options)

-t, –target : 要检查的Xcode target

-b, –buildConfig : 要检查的Xcode编译配置

-r, –rules : 要使用的规则(默认是空,[]),这value必须是规则的短名称

–onlyRules : 只用这一条规则,value必须是规则的短名称,使用这个选项会覆盖所有其他规则选定的选项

-g, –ruleTags : 要应用的规则tag,默认是[“Recommended”],选择拥有指定tag的规则

–excludedRules : 排除规则,默认是空[], 排除指定规则,哪怕这些规则已经被选中

-c, –configFile : 指定一个配置文件,如果项目已经有一个配置文件了,这个将覆盖它

-x, –fileExclusionPrefixes 排除带有特定前缀的文件,例如”HG”,将排除”HGObject.m”和”NSString+HGExtensions.m”

–fileExclusionXcodeGroups : 排除Xcode项目中group,默认是[“Vendor”]

–fileExclusionRegexes : 按照正则表达式排除文件,默认是空[],按照给定的ICU正则表达式匹配的绝对路径排除文件

–minErrorStatusSeverity <”Concern”/“Warning”/“Error”/“Fatal”/“None”> : 最小的诊断严重性来返回非零的退出状态,默认是Error,如果一个诊断在给定的严重性级别或者更高,则返回一个非0的值,如果设置为None,则永远返回0(0即成功)

–workspace : 指定构建项目的Xcode工作空间。指定一个工作空间(伴随着scheme 选项)如果这个项目无法单独编译起来(例如cocoapod集成的情况

–scheme : 指定编译项目的scheme,(一般伴随着workspace选项一起),如果这个项目无法单独编译起来(例如cocoapod集成的情况)

–numConcurrentJobs : 多线程检查的数量,如果这个值是忽略或0,Faxu Pas会自己定一个合适的值

–extraCompilerArgs : 额外的编译参数,默认是空[],用于分析源代码文件

–extraXcodebuildArgs : 额外的xcodebuild参数,默认是[],用于xcodebuild运行时

-f, –fullBuild : 在检查前先运行项目,默认是no,如果在构建过程中项目生成源文件或者在项目源代码的成功解释,则为yes,否则就会用完成的构建来替代。这样会花费更多时间,但是会有效减少一些cased有关false的数量

–cacheBuildLog : 缓存项目构建日志,默认是yes,这会加大检查过程中的运行时间

–useOwnModulesCache : 使用自己的模块来缓存,默认是yes,这是为了避免和系统缓存冲突

–processOnlyTargetPCHs : 处理单一target预编译头文件,默认是yes,关闭这个设置将使得检查变得很慢,在某些共享的预编译头文件中可能是必须的

-v, –verbose : 可以打印出更多的日志细节,默认是no

-o, –outputFormat <”human” / “json” / “plist” / “xcode”> : 输出格式,默认”human”

规则列表

UndetachedDelegate

未解绑的delegate或data source

Tags:BestPractice, Recommended

当一个对象将自己设置成delegate或者其成员的数据源,必须在[NSObject dealloc]里解除引用.

Options:
UndetachedDelegate.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


InvalidStringsFile

应用于本地化项目的无效字符串资源文件(字符串资源文件应该是有效的plist)

Tags(点击tag可跳转): Recommended, Localization

Options:

InvalidStringsFile.ignoredFileRegexes:
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


StringsFileEncoding

字符串资源文件不是UTF-8编码

应用于.git管理的项目

Tags:Recommended, Localization, VCS, BestPractice、

git选择使用UTF-8编码,并不能很好的支持其他编码(例如UTF-16)。会把UTF-16文件当做二进制文件,不能逐行显示差别

Options:

StringsFileEncoding.ignoredFileRegexes:
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


UIKitKVO

使用KVO观察UIKit对象

Tags(点击tag可跳转): Recommended, APIUsage

UIKit框架的类通常不支持KVO,如果KVO在这类property上工作,会发生不可知的行为,且未来也不能保证能运行良好

Options:
UIKitKVO.allowSubclasses
(Boolean. Default: yes)
允许观察自定义的实现了KVO的UIKit子类(这种情况不抛出警告)

UIKitKVO.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


UnnecessaryNullCheck

在free()调用前检查多余的NULL

Tags(点击tag可跳转): Recommended, Pedantic

free(NULL)是空指令,什么也不做

扩展阅读:
free() man page

Options:
UnnecessaryNullCheck.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


RetinaImagesResolution

非预期的高清图片分辨率

Tags(点击tag可跳转): Recommended, Resources

@2x或@3x的图片资源必须和低倍的图片尺寸相匹配(即刚好是其2倍或3倍尺寸,因为无论屏幕尺寸多大,其展示的上下文是完全一样的),否则图片的有效分辨率会不匹配其上下文的分辨率,将导致出现一个模糊的图片,边框空白或者溢出

扩展阅读:
Apple Developer: Optimizing for High Resolution

Options:
RetinaImagesResolution.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


AssertionSideEffects

断言的副作用

Tags(点击tag可跳转): Recommended, BestPractice

如果断言宏正文包含了无getter函数或方法的调用,则该规则会抛出警告

断言不应该有副作用,因为正常情况下release打包后是失效的 - 程序的行为不应该依赖断言生效与否

本条规则涉及范围是Foundation的断言宏

Options:
AssertionSideEffects.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


SuspiciousResources

可疑的bundle资源

可疑的bundle资源

Tags(点击tag可跳转): Recommended, Resources

许多文件是项目的一部分,只能在build或者development的时候生效(例如Xcode配置文件),如果添加到bundle资源中就会导致错误

Options:
SuspiciousResources.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


NullCoalescingOp

和空对象合并操作

Tags(点击tag可跳转): Recommended, Style

(obj ? obj : other)的表达式可以写成obj ?: other

Options:
NullCoalescingOp.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


LoadMethodWithoutAutoreleasePool

[NSObject load]方法中没有@autoreleasepool

该规则适用于iOS 5或Mac OS 10.7 及之前的项目target中

Tags(点击tag可跳转): Recommended, BestPractice

要执行+[NSObject load],需要手动建立一个自动释放池

Options:
LoadMethodWithoutAutoreleasePool.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


UnknownResourceCodeReference

代码引用未知资源

应用于target上

Tags(点击tag可跳转): Recommended, Resources

从硬盘上实时加载的资源,本应该提前放在正确路径的bundle中。注意iOS模拟器运行在Mac上,和其不同,iOS设备有一个区分大小写的系统

Options:
UnknownResourceCodeReference.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


StringsdictWithoutStrings

.stringdict文件没有匹配.string文件

应用于本地化项目

Tags(点击tag可跳转): Recommended, Localization

如果一个.stringsdict文件作为资源包含进项目,一个同名的.string文件也需要包含进项目,即使是空的,否则将不能从.stringsdict文件中读取翻译

扩展阅读:
Foundation Release Notes for OS X v10.9

Options:
StringsdictWithoutStrings.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


InitializeSuperInvocation

+[NSObject initialize]调用了super方法

Tags(点击tag可跳转): Recommended, BestPractice

+[NSObject initialize]的实现中不应该调用了super方法,initialize这个方法比较特殊,它每一个子类是独立的。

Options:
InitializeSuperInvocation.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


CompilerWarnings

推荐的编译警告选项

Tags(点击tag可跳转): Recommended, BestPractice, Config

Some compiler warnings and warning groups are so useful that they should be
enabled at all times.

补充阅读:
Clang Compiler User’s Manual: Controlling Diagnostics via Command Line Flags

Xcode Build Setting Reference

GCC Warning Options (many are the same in Clang)

Options:
CompilerWarnings.flags
字符串数组,默认是[“-Werror”, “-Wall”, “-Wextra”, “-Wshadow”, “-Wfloat-equal”, “-Wundef”, “-Wnewline-eof”, “-Wempty-body”, “-Wconversion”, “-Wsign-compare”, “-Wreturn-type”, “-Wdeprecated-implementations”, “-Wimplicit-retain-self”]

CompilerWarnings.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


UnsupportedWeakReference

将一个不能weak的对象指定为weak属性

用于OS X target

Tags(点击tag可跳转): Recommended

在OS X中,许多类是不能创建weak实例(参见苹果文档中详细列表)

The Clang编译器会为上述不能weak的变量抛出警告

推荐阅读:
Transitioning to ARC Release Notes: Frequently Asked Questions: Which classes don’t support weak references?

Options:
UnsupportedWeakReference.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


HardcodedUIString

UI 字符串没有本地化

应用于本地化项目

Tags(点击tag可跳转): Recommended , Localization

所有的字符串倾向于使用NSLocalizedString()来本地化

Options:
HardcodedUIString.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


HardcodedSelfClass

硬编码自身类引用

Tags(点击tag可跳转): Recommended , BestPractice

如果一个Objective-C类(或者一个类实例)向自身发一个消息,例如[FOOThing alloc],推荐使用self来代替(例如[self alloc] or [[self class] alloc])这样实际的类将受到消息,子类化行为将不会被阻止

Options:

HardcodedSelfClass.warnOnlyAboutAlloc
(Boolean. Default: no)
只限制alloc操作

HardcodedSelfClass.checkOnlyFactoryMethods
(Boolean. Default: no)
只检查工厂方法

HardcodedSelfClass.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


MacroBasedIncludeGuard

用宏保障#include引用一次

Tags(点击tag可跳转): Recommended , BestPractice

通过#pragma once宏定义来检查是否引用了一次,能够简化头文件


RestrictedDirectMethodCall

限制直接方法调用

Tags(点击tag可跳转): Recommended , APIUsage

许多系统类不能直接调用

本规则将不会对覆盖方法调用父类实现的情况抛出警告

Options:
RestrictedDirectMethodCall.allowInSubclass
(Boolean. Default: yes)
允许从子类直接调用,如果调用定义在父类的限制方法则不会抛出警告

RestrictedDirectMethodCall.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


RecommendedVCSIgnores

推荐的版本控制系统忽略项

应用于git管理的项目

Tags(点击tag可跳转): Recommended , VCS

当许多文件被建议在版本控制系统中忽略却实际上没有忽略则会抛出警告,反之亦然

Options:
RecommendedVCSIgnores.workspaceIgnored
(Boolean. Default: no)
Xcode工作空间数据应该被忽略

RecommendedVCSIgnores.cocoaPodsIgnored
(Boolean. Default: no)
CocoaPods数据应该被忽略(例如Pods文件夹,只有当CocoaPods在使用时才会警告)

RecommendedVCSIgnores.carthageBuildIgnored
(Boolean. Default: yes)
Carthage/Build数据应该被忽略(例如Pods文件夹,只有当Carthage在使用时才会警告)

RecommendedVCSIgnores.carthageCheckoutsIgnored
(Boolean. Default: no)
Carthage/Checkouts数据应该被忽略(例如Pods文件夹,只有当Carthage在使用时才会警告)

RecommendedVCSIgnores.appCodeUserDataIgnored
(Boolean. Default: yes)
用户指定的AppCode数据应该被忽略(例如.idea文件夹下的特定文件,只有当该文件夹存在时才会警告)

RecommendedVCSIgnores.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


RetainingImmutableProperty

没复制不可变property

Tags(点击tag可跳转): Recommended , BestPractice

如果用retain语义指定了一个@property(该属性是NSCopying类型的不可变属性),该规则会生成一个警告,因为这样也依然会产生一个可变子类变量(例如NSString)

这个规则帮助避免一个property的值发生改变却没有setter能调用的情况(例如:可变对象的setter是可以调用的)

Options:
RetainingImmutableProperty.ignorePrivateProperties
(Boolean. Default: yes)
不警告公共头文件以外的私有property

RetainingImmutableProperty.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


22 CompleteNotificationCenterDetachment

解除NSNotificationCenter绑定

Tags(点击tag可跳转): Recommended , BestPractice

当一个对象移除了自身作为所有通知的响应者(-[NSNotificationCenter removeObserver:] self)时抛出警告

如果一个父类或者一个子类希望保持观察通知,就会产生问题了。推荐在离开时解绑之前绑定在自身上指定的通知,而不是全部通知。

在-dealloc中移除所有通知并不会触发本规则

Options:
CompleteNotificationCenterDetachment.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


MissingAPIUsageDescription

缺少API使用描述

应用于应用target

Tags(点击tag可跳转): Recommended , Config

一些API(例如访问联系人或者日历)需要在app的metadata(info.plist)里添加使用描述。当系统询问用户是否允许app访问时会将描述呈现给用户,本规则在使用类似功能然而没有添加相关描述时抛出警告

Options:
MissingAPIUsageDescription.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


XIBRuntimeAttributeMismatch

XIB实时属性不匹配

Tags(点击tag可跳转): Recommended , Resources

当一个自定义XIB实时属性不能匹配对应类的源代码时抛出警告

A key path that doesn’t match any of the class properties or setter methods
yields a diagnostic, as does a mismatch in the type of the assigned value and
the value type declared for the property or setter.


ThreadUnsafeInstanceCaching

全局持有一个线程不安全的类实例

Tags(点击tag可跳转): Recommended

当全局存储一个对象指针指向线程不安全的类的实例时抛出警告

-[NSThread threadDictionary]能够用于缓存线程不安全的类的实例 - 每个线程都有一个这样的实例

这个规则会忽略代码复写了UIKit或者AppKit的子类(或者category)的情况,因为会假设主线程访问永远是安全的

补充阅读:
Threading Programming Guide: Thread Safety Summary

Options:ThreadUnsafeInstanceCaching.classNames
(字符串数组列表,默认是[“NSDateFormatter”, “NSNumberFormatter”, “NSMutableArray”, “NSMutableAttributedString”, “NSMutableCharacterSet”, “NSMutableData”, “NSMutableDictionary”, “NSMutableSet”, “NSMutableString”],这些线程不安全的类在本规则响应的范围内)

ThreadUnsafeInstanceCaching.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)


MissingTranslation

翻译缺失

应用于本地化项目

Tags(点击tag可跳转): Recommended , Localization

如果翻译缺少用于NSLocalizedString参数或者其变量的key,本规则会抛出警告

Options:

MissingTranslation.checkDevRegion
(Boolean. Default: no)
当缺少development region翻译时产生警告
(如果你不使用key作为隐式默认值时,就把这个设置为yes)

MissingTranslation.ignoredKeyPrefixes
(字符串数组,默认是[],忽略key的前缀,当缺少该前缀开头的key时不产生警告)

MissingTranslation.ignoredFileRegexes
(设置要忽略的文件路径的正则表达式,值为正则表达式字符串的数组,正则表达式匹配的是需要忽略的文件的完成路径,默认是)

_LocalizationRules.localizedStringRoutines
(字符串数组,默认是[],用于替代NSLocalizedString的函数字符串,第一个参数假定是string key)


RestrictedMethodOverride