Static Code Analysis for iOS: SwiftLint, Infer, and OCLint – Installation, Integration, and Comparison
This guide explains how to set up and use static analysis tools SwiftLint, Infer, and OCLint for iOS projects, covering installation methods, Xcode integration, custom configuration, report generation, and a comparative overview to help choose the right solution.
Introduction
As projects grow, manual code review becomes impractical, making automated static analysis essential. Static analysis scans source code without execution using lexical, syntactic, control‑flow, and data‑flow techniques to verify conformity, safety, reliability, and maintainability.
SwiftLint
SwiftLint enforces Swift style and conventions by hooking into Clang and SourceKit to obtain an AST.
Installation
Two options:
Homebrew (global):
$ brew install swiftlintCocoaPods (debug only):
pod 'SwiftLint', :configurations => ['Debug']Integration into Xcode
Add a Run Script Phase to the Build Phases of the target.
If installed via Homebrew:
if which swiftlint > /dev/null; then
swiftlint
else
echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fiIf installed via CocoaPods:
"${PODS_ROOT}/SwiftLint/swiftlint"Running SwiftLint
Build the project (⌘ B); the script runs automatically and warnings appear in the build log or Xcode warnings pane.
Customization
Create a .swiftlint.yml at the project root to disable rules, exclude paths, and adjust thresholds. Example snippet:
disabled_rules:
- colon
- trailing_whitespace
- vertical_whitespace
- function_body_length
opt_in_rules:
- empty_count
included:
- Source
excluded:
- Carthage
- Pods
- Source/ExcludedFolder
- Source/ExcludedFile.swift
analyzer_rules:
- explicit_self
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
allowed_symbols: ["_"]
identifier_name:
min_length:
error: 4
excluded:
- id
- URL
- GlobalAPIKey
reporter: "xcode"Custom rules can also be defined.
Generating a Report
Use the HTML reporter:
# reporter type (xcode, json, csv, checkstyle, junit, html, emoji, sonarqube, markdown)
$ swiftlint lint --reporter html > swiftlint.htmlxcodebuild
xcodebuild is the built‑in Xcode command‑line tool. Typical commands:
# Non‑pod project, Debug, simulator SDK
xcodebuild -target TargetName -configuration Debug -sdk iphonesimulator
# Pod‑based project, Release, device SDK
xcodebuild -workspace WorkspaceName.xcworkspace -scheme SchemeName -configuration Release
# Clean build products
xcodebuild -workspace WorkspaceName.xcworkspace -scheme SchemeName -configuration Release cleanInfer
Infer, developed by Facebook, performs static analysis for C, Objective‑C, C++, and Java. It detects resource leaks, nullability issues, retain cycles, and premature nil usage.
Installation & Usage
$ brew install inferRun Infer while skipping Pods:
$ cd projectDir
# Skip analysis of Pods
$ infer run --skip-analysis-in-path Pods -- xcodebuild -workspace "Project.xcworkspace" -scheme "Scheme" -configuration Debug -sdk iphonesimulatorResults are placed in infer-out (including bug.txt and report.csv ). To view HTML:
$ infer explore --htmlFor a full analysis, clean the project first:
$ xcodebuild -workspace "Project.xcworkspace" -scheme "Scheme" -configuration Debug -sdk iphonesimulator clean
$ infer run --skip-analysis-in-path Pods -- xcodebuild -workspace "Project.xcworkspace" -scheme "Scheme" -configuration Debug -sdk iphonesimulatorOCLint
OCLint, built on Clang tooling, supports C, C++, and Objective‑C and can detect bugs, style violations, and complexity issues.
Installation
$ brew tap oclint/formulae
$ brew install oclint
# Verify version
$ oclint --versionVersion 0.13 is installed via Homebrew; version 0.15 can be built from source.
Building OCLint 0.15 from Source
$ brew install cmake ninja
$ git clone https://github.com/oclint/oclint
$ cd oclint-scripts && ./make
# The built binary is in build/oclint-releaseSet the PATH in .zshrc or .bash_profile :
OCLint_PATH=/Users/zhangferry/oclint/build/oclint-release
export PATH=$OCLint_PATH/bin:$PATH
source .zshrcInstalling xcpretty
$ gem install xcprettyUsing OCLint
Disable the index store in Xcode ( COMPILER_INDEX_STORE_ENABLE = NO ) and add a similar setting for Pods in the Podfile.
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['COMPILER_INDEX_STORE_ENABLE'] = "NO"
end
end
endGenerate a compilation database and run OCLint:
$ xcodebuild -workspace ProjectName.xcworkspace -scheme ProjectScheme -configuration Debug -sdk iphonesimulator | xcpretty -r json-compilation-database -o compile_commands.json
$ oclint-json-compilation-database -e Pods -- -report-type html -o oclintReport.html -rc LONG_LINE=9999 -max-priority-1=9999 -max-priority-2=9999 -max-priority-3=9999Packaging as an Xcode Target
Create an Aggregate target named “OCLint”, add a Run Script phase with:
# Change to project root
cd ${SRCROOT}
# Clean and generate compilation database
xcodebuild clean
xcodebuild | xcpretty -r json-compilation-database
# Run OCLint and output Xcode‑style warnings
oclint-json-compilation-database -e Pods -- -report-type xcodeComparison
SwiftLint
Infer
OCLint
Supported Languages
Swift
C, C++, Objective‑C, Java
C, C++, Objective‑C
Ease of Use
Simple
Relatively Simple
Relatively Simple
Integrates into Xcode
Yes
No
Yes
Built‑in Rule Richness
Many, includes style checks
Few, focuses on potential bugs
Many, includes style checks
Rule Extensibility
Yes
No
Yes
References
OCLint Code Review – Improving Code Quality
Using OCLint in Xcode
Infer’s Working Mechanism
LLVM & Clang Introduction
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.