Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to improve iOS Code quality through static Analysis

2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article focuses on "how to improve the quality of iOS code through static analysis", interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how to improve the quality of iOS code through static analysis.

With the expansion of the project, it is more and more unrealistic to rely on manual codereview to ensure the quality of the project, so it is necessary to rely on an automatic code review tool: program static analysis.

Program static analysis (Program Static Analysis) is a kind of code analysis technology that scans the program code through lexical analysis, syntax analysis, control flow, data flow analysis and other technologies without running the code to verify whether the code meets the specifications such as standardization, security, reliability, maintainability and so on. (from Baidu encyclopedia)

Lexical analysis and syntax analysis are carried out by the compiler, so in order to complete the static analysis of the iOS project, we need the help of the compiler. The static analysis of OC language can be done entirely through Clang, and the static analysis of Swift needs the help of SourceKit in addition to Clange.

The static analysis tools corresponding to Swift language are Infer and OCLitn corresponding to SwiftLint,OC language. The following is an introduction to the installation and use of various static analysis tools.

SwiftLint

SwiftLint can be used for static analysis of Swift projects. SwiftLint is a tool for mandatory checking of Swift code styles and rules. Its implementation is Hook Clang and SourceKit to be able to use AST to represent more accurate results of source code files. Clange we understand, then what is the use of SourceKit?

SourceKit, which is included in the main repository of the Swift project, is a toolset that supports most of Swift's source code operation features: source code parsing, syntax highlighting, typesetting, automatic completion, cross-language header generation, and so on.

Installation

There are two ways to install, one of which is optional: method one: through Homebrew

$brew install swiftlint

This is a global installation and can be used by various applications. Method 2: through CocoaPods

Pod 'SwiftLint',: configurations = > [' Debug']

This approach is equivalent to integrating SwiftLint into the project as a three-party library, because it is just a debugging tool, so we should specify it to take effect only in the Debug environment.

Integrate into Xcode

We need to add a Run Script Phase to the Build Phases in the project. If you installed it through homebrew, your script should look like this.

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

If you installed it through cocoapods, your script should look like this:

"${PODS_ROOT} / SwiftLint/swiftlint"

Run SwiftLint

Type CMD + B to compile the project, and after the compilation, we will run the script we just added, and then we can see a lot of warnings in the project. Sometimes the build information cannot be filled in the project code, and we can check it in the compiled log log.

Customization

There are too many SwiftLint rules, and if we don't want to enforce a rule, or if we want to filter out the analysis of the Pods library, we can configure SwfitLint.

Create a new .swiftlint.yml file in the root directory of the project, and fill in the following:

Disabled_rules: # rule identifiers to exclude from running-colon-trailing_whitespace-vertical_whitespace-function_body_lengthopt_in_rules: # some rules are only opt-in-empty_count # Find all the available rules by running: # swiftlint rulesincluded: # paths to include during linting `--path` is ignored if present. -Sourceexcluded: # paths to ignore during linting. Takes precedence over. -Carthage-Pods-Source/ExcludedFolder-Source/ExcludedFile.swift-Source/*/ExcludedFile.swift # Exclude files with a wildcardanalyzer_rules: # Rules run by `swiftlint analyze` (experimental)-explicit_self# configurable rules can be customized from this configuration file# binary rules can set their severity levelforce_cast: warning # implicitlyforce_try: severity: warning # explicitly# rules that have both warning and error levels Can set just the warning level# implicitlyline_length: 11 million they can set both implicitly with an arraytype_body_length:-300 # warning-400 # error# or they can set both explicitlyfile_length: warning: 500 error: 120 percent naming rules can set warnings/errors for min_length and max_length# additionally they can set excluded namestype_name: min_length: 4 # only warning max_length: # warning and error warning: 40 error: 50 excluded: iPhone # excluded via string allowed_symbols: ["_ "] # these are allowed in type namesidentifier_name: min_length: # only min_length error: 4 # only error excluded: # excluded via string array-id-URL-GlobalAPIKeyreporter:" xcode "# reporter type (xcode Json, csv, checkstyle, junit, html, emoji, sonarqube, markdown)

A rules prompt is as follows, and its corresponding rules name is function_body_length.

! Function Body Length Violation: Function body should span 40 lines or less excluding comments and whitespace: currently spans 43 lines (function_body_length)

Fill in the rules under disabled_rules that we don't want to follow.

Excluded sets the directories we want to skip checking. Carthage, Pod, and SubModule can generally be filtered out.

Others, such as file length (file_length) and type name length (type_name), can be adjusted by setting specific values.

In addition, SwiftLint also supports custom rules, and we can define our own rule according to our own needs.

Generate a report

If we want to generate a report on this analysis, that's fine (the command is swiftlint installed through homebrew):

# reporter type (xcode, json, csv, checkstyle, junit, html, emoji, sonarqube, markdown) $swiftlint lint-- reporter html > swiftlint.html

Xcodebuild

Xcodebuild is the built-in compilation command of xcode, which we can use to compile and package our iOS project. Infer and OCLint are analyzed based on the compiled products of xcodebuild, so it is necessary to briefly introduce it.

Generally, to compile a project, we need to specify the project name, configuration,scheme,sdk and other information. Here are a few simple commands and instructions.

# for a project without pod, the name of target is TargetName. Under Debug, specify the simulator sdk environment to compile the xcodebuild-target TargetName-configuration Debug-sdk iphonesimulator# project with pod. The workspace is TargetName.xcworkspace. Under Release, scheme is TargetName. Specify the real machine environment to compile. If you do not specify the simulator environment, you will verify the certificate xcodebuild-workspace WorkspaceName.xcworkspace-scheme SchemeName Release# clearly the compiled product of the project, xcodebuild-workspace WorkspaceName.xcworkspace-scheme SchemeName Release clean.

Subsequent use of the xcodebuild command requires replacing these parameters with those of your own project.

Infer

Infer is a static analysis tool developed by Facebook for C, OC and Java languages. It supports the analysis of iOS and Android applications at the same time. It is used for static analysis of Facebook internal applications such as Messenger, Instagram and other applications. It mainly detects hidden problems, including the following:

Resource leak, memory leak

Non-null detection of variables and parameters

Circular reference

Premature nil operation

Custom rules are not supported at this time.

Install and use $brew install infer

Run infer

$cd projectDir# skips the analysis of Pods $infer run-- skip-analysis-in-path Pods-- xcodebuild-workspace "Project.xcworkspace"-scheme "Scheme"-configuration Debug-sdk iphonesimulator

We will get an infer-out folder containing various code analysis files in txt,json and other file formats. When this is not easy to view, we can convert it to html format:

$infer explore-html

Click trace and we will see the context of the problem code.

Because Infer compiles incrementally by default, it only analyzes the changed code. If we want to compile as a whole, we need to clean the project:

$xcodebuild-workspace "Project.xcworkspace"-scheme "Scheme"-configuration Debug-sdk iphonesimulator clean

Run Infer again to compile.

$infer run-- skip-analysis-in-path Pods-- xcodebuild-workspace "Project.xcworkspace"-scheme "Scheme"-the general principle of configuration Debug-sdk iphonesimulatorInfer

The static analysis of Infer is mainly divided into two phases:

1. Capture phase

Infer captures the compilation command and translates the file into an intermediate language within Infer.

This kind of translation is similar to compilation, where Infer takes information from the compilation process and translates it. This is why we call Infer with a compile command, such as infer-- clang-c file.c, infer-- javac File.java. The result is that the file is compiled as usual and translated into an intermediate language by Infer, leaving it for the second phase of processing. It is particularly important to note that if no files are compiled, no files will be parsed.

Infer stores the intermediate files in the result folder, which is generally created under the directory where infer is run, named infer-out/.

2. Analysis stage

During the analysis phase, Infer analyzes all files under infer-out/. When analyzing, each method and function is analyzed separately.

When analyzing a function, if an error is found, the analysis will be stopped, but this does not affect the continued analysis of other functions.

So when you check for problems, after fixing the errors in the output, you need to continue to run Infer to check until you confirm that all the problems have been fixed.

In addition to being displayed in standard output, errors are output to the file infer-out/bug.txt, and we filter these problems to show only those that are most likely to exist.

In the result folder (infer-out), there is also a csv file, report.csv, which contains all the information generated by Infer, including: errors, warnings and messages.

OCLint

OCLint is a library based on Clange Tooling that supports extensions and has a larger scope of detection than Infer. Not only is the bug hidden, but some code normative issues, such as naming and function complexity, are also within the scope of detection.

Install OCLint

OCLint is generally installed through Homebrew

$brew tap oclint/formulae $brew install oclint

The version installed through Hombrew is 0.13.

$oclint-versionLLVM (http://llvm.org/): LLVM version 5.0.0svn-r313528 Optimized build. Default target: x86_64-apple-darwin19.0.0 Host CPU: skylakeOCLint (http://oclint.org/): OCLint version 0.13. Built Sep 18 2017 (08:58:40).

I have run OCLint on two projects using Xcode11. One instance project runs normally, while the other complex project fails. The following error is reported:

1 error generated1 error generated...oclint: error: cannot open report output file.... / onlintReport.html

I don't know why, but if you want to see if 0.13 can be used, skip to installing xcpretty. If you have the same problem, you can come back and install the oclint0.15 version.

OCLint0.15

I found this problem and the corresponding solution here in oclint issuse # 547.

We need to update oclint to version 0.15. The latest version on brew is 0.13. The latest version on GitHub is 0.15. I downloaded the release0.15 version on github, but the package was not compiled. I don't know if the authorities made a mistake and had to compile it manually. Because the compilation requires downloading llvm and clange, which are larger, I upload the compiled package directly to CodeChecker here.

If you don't care about the compilation process, you can download the compiled package and skip to the step of setting the environment variable.

Compile OCLint

1. Install the two compilation tools, CMake and Ninja

$brew install cmake ninja

2. Clone OCLint project

$git clone https://github.com/oclint/oclint

3. Enter the oclint-scripts directory and execute the make command

$. / make

After success, the build folder appears, and there is an oclint-release in it, which is the compiled oclint tool.

Set the environment variables of the oclint tool

The purpose of setting environment variables is for us to have quick access. Then we need to configure the PATH environment variable and note that the path of OCLint_PATH is the path where you store the oclint-release. Add it to the .zshrc or to the end of the .bash _ profile file:

OCLint_PATH=/Users/zhangferry/oclint/build/oclint-releaseexport PATH=$OCLint_PATH/bin:$PATH

Execute source .zshrc, refresh the environment variables, and then verify that oclint is installed successfully:

$oclint-versionOCLint (http://oclint.org/):OCLint version 0.15.Built May 19 2020 (11:48:49).

The appearance of this introduction means that we have completed the installation.

Install xcpretty

Xcpretty is a scripting tool for formatting xcodebuild output, and the parsing of oclint depends on its output. It is installed as follows:

Use of $gem install xcprettyOCLint

You need some preparation before using OCLint, and you need to set the compilation item COMPILER_INDEX_STORE_ENABLE to NO.

Set COMPILER_INDEX_STORE_ENABLE under Building Settings in Project and Targets to NO

Add the following script before target' target' do in podfile to change the compilation configuration of each pod to this option

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 endend usage

1. Enter the project root directory and run the following script:

$xcodebuild-workspace ProjectName.xcworkspace-scheme ProjectScheme-configuration Debug-sdk iphonesimulator | xcpretty-r json-compilation-database-o compile_commands.json

Some information from the xcodebuild compilation process will be recorded as a file compile_commands.json. If we see the file in the root directory of the project, and there is content in it, it proves that we have completed the first step.

2. We convert the json file to an easy-to-view html to filter out the analysis of the Pods file. In order to prevent the maximum number of lines, we add a limit on the number of lines:

$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=9999

An oclintReport.html file will eventually be generated.

OCLint supports custom rules because its own rules are already rich, and the requirements for custom rules should be small, so there is no attempt.

Encapsulation script

OCLint, like Infer, is executed by running several scripting languages. We can encapsulate these commands into a script file. Take OCLint as an example, Infer is similar:

#! / bin/bash# mark sure you had install the oclint and xcpretty# You need to replace these values with your own project configurationworkspace_name= "WorkSpaceName.xcworkspace" scheme_name= "SchemeName" # remove historyrm compile_commands.jsonrm oclint_result.xml# clean project#-sdk iphonesimulator means run simulatorxcodebuild-workspace $workspace_name-scheme $scheme_name-configuration Debug-sdk iphonesimulator clean | | (echo "command failed"; exit 1) # export compile_commands.jsonxcodebuild-workspace $workspace_name-scheme $scheme_name-configuration Debug-sdk iphonesimulator\ | xcpretty-r json-compilation-database-o compile_commands.json\ | | (echo "command failed"; exit 1); # export report html# you can run `oclint- help`to see all USAGEoclint-json-compilation-database-e Pods-- report-type html-o oclintReport.html\-disable-rule ShortVariableName\-rc LONG_LINE=1000\ | (echo "command failed"; exit 1); open-a "/ Applications/Safari.app" oclintReport.html

Several parameters of the oclint-json-compilation-database command describe:

-e files that need to be ignored for analysis, and warnings for these files will not appear in the report

-the threshold of the rule to be covered by rc. Here, you can customize the threshold of the project. The default threshold is

-the rules supported by enable-rule, which are supported by oclint by default, can be combined with-disable-rule to filter out some rule lists.

-rules that need to be ignored by disable-rule, set according to project requirements

Using OCLint in Xcode

Because OCLint provides output styles in xcode format, we can put it in Xcode as a script.

1. Under the TARGETS of the project, click "+" below, and select Aggregate under cross-platform. Enter a name, which is named OCLint.

2. Select the Target, enter Build Phases, add Run Script, and write the following script:

# Type a script or drag a script file from your workspace to insert its path.# built-in variable cd ${SRCROOT} xcodebuild clean xcodebuild | xcpretty-r json-compilation-databaseoclint-json-compilation-database-e Pods-- report-type xcode

You can see that this script is the same as the script above, except that the-report-type of the oclint-json-compilation-database command is changed from html to xcode. OCLint as a target itself runs in a specific environment, so xcodebuild can omit configuration parameters.

3. If we compile the project and execute the script task through CMD + B, we will get the warning information that can locate the code:

At this point, I believe you have a deeper understanding of "how to improve the quality of iOS code through static analysis". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report