记录使用 SwiftLint检测代码内的硬编码字符串

花了 N多天的时间,总算达到了预期的效果(并没有,依旧有很多问题,加了很多特殊代码的排除规则,但也算基本能用了),记录一下,希望能帮到有类似需求的iOSer吧。

SwiftLint: github.com/realm/Swift...

1,先使用命令行安装 SwiftLint工具,命令如下:

复制代码
brew install swiftlint

2,在项目内接入 SwiftLint,可使用 Cocoapods,我使用的 SPM接入;

3,在项目根目录下(与.xcodeproj文件同层级)创建 .swiftlint.yml文件;

4,将下述规则代码粘贴进去,因为我这边的项目是 SwiftUI,所以控件都是用的 SwiftUI相关的。如果使用的是 UIKit,则需要替换一下;

SwiftLint 复制代码
only_rules:
  - custom_rules

excluded:
  - "**/Tests/**"
  - "**/UITests/**"
  - "**/Pods/**"
  - "**/DerivedData/**"

custom_rules:
  check_hardcoded_strings:
    name: "Hardcoded String"
    regex: '(?<!LocalizedStringKey\()(Text\(\s*"(?!.*[\\$]\(.*?\))([^"\\]|\\.)+"\s*\)|(Label|TextField|TextEditor|Alert|Picker|Menu|contextMenu|toolbar|navigationTitle|alert|confirmationDialog|prompt|navigationBarTitle|tabItem|Section|Toggle|ProgressView|Link|Gauge|DatePicker|Stepper|ColorPicker|SecureField|GroupBox|DisclosureGroup|OutlineGroup|LabeledContent)\([^)]*"(?!\s*$)(?!.*(systemImage|imageNamed|systemName|NSLocalizedString\s*\(|localizedString|String\.localized|DateFormatter\.\w+\.string\())[^"\n]+"[^)]*\))'
    message: "Avoid hard-coded strings and use localized strings instead."
    severity: error
    exclude:
      # SF Symbols icons
      - '\.(systemImage|symbolName)\s*:\s*"[a-z]+(\.[a-z]+)+"' # Match all SF Symbols formats
      - 'Label\([^,]+,\s*systemImage\s*:\s*"[^"]+"\)' # Enhanced Label detection
      - 'Image\(systemName:\s*"[^"]+"\)' # Cover all Image initializations
      
      # Image sources
      - 'image(Name[d]?|Resource|Path)\s*[:=]\s*"[^"]+"'
      - '\.image\(\s*"[^"]+"\)'
      
      # Basic exclusions
      - 'Text\(\s*"\s*"\s*\)' # Match empty strings and whitespace-only
      - 'Text\("[0-9]+(\.[0-9]+)?"\)' # Numbers
      - '([+]\s*Text\(\s*"\s*"\s*\))|(Text\(\s*"\s*"\s*\)\s*[+])' # Handle concatenation scenarios
      - '(?s)(HStack|VStack|ZStack)\s*\{.*?Text\(\s*"\s*"\s*\).*?\}' # Nested structure detection
      
      # Dynamic content exclusions
      - 'Text\(\s*[a-zA-Z_]\w*\s*\)' # Text(variable)
      - 'Text\(".*?[\\$]\(.*?\).*?"\)' # Any interpolation ($ or backslash)
      - 'Text\(\s*".*?\\.*?"\s*\)' # Contains escape characters
      
      # Special control handling
      - "\\bButton\\("
      - "\\bnavigationBarItems\\("
      - "TextField\\(\\s*\"\"\\s*,.*\\)"
      - "NavigationLink\\(\\s*\"\"\\s*,.*\\)"
      - "\\.accessibilityLabel\\(Text\\(.*\\)\\)"
      - "Group\\s*\\{.*?Text\\(.*?\\).*?\\}"
      
      # Other exclusions
      - "(?s)/\\*.*?\\*/"
      - "//.*?(\\n|$)"
      - "case\\s+\""
      - "@selector\\("
      - "(#if DEBUG)(.|[\\r\\n])*?(#endif)"
      - "(?s)preview\\s*\\{.*?\\}"
      - "assert\\(.*\\)"
      - "fatalError\\(.*\\)"
      - "UserDefaults\\.standard\\.string\\(forKey:.*\\)"
      - "Notification\\.Name\\(rawValue:.*\\)"
      - "NSLocalizedString\\([^)]*\\)"

5,在项目 Target - Build Phase内新增一个 New Run Script Phase,用来在编译时运行脚本代码;

6,在这个脚本内贴入下述代码,这里要注意 SwiftLint在 M芯片和 Intel芯片的 Mac上的安装路径是不一致的:

bash 复制代码
# Type a script or drag a script file from your workspace to insert its path.
SWIFTLINT_PATHS=(
  "/opt/homebrew/bin/swiftlint"  # the path fot M-series chip
  "/usr/local/bin/swiftlint"     # the path for Intel chip
)

CONFIG="${SRCROOT}/.swiftlint.yml"
SOURCES="${SRCROOT}"

# Trying to find out an available path
SWIFTLINT=""
for path in "${SWIFTLINT_PATHS[@]}"; do
  if [ -f "$path" ]; then
    SWIFTLINT="$path"
    break
  fi
done

echo "=== CHECK SWIFTLINT ENV ==="
echo "SwiftLint path: $SWIFTLINT"

if [ -n "$SWIFTLINT" ]; then
  echo "SwiftLint version: $($SWIFTLINT version)"
  "$SWIFTLINT" lint \
    --config "$CONFIG" \
    "$SOURCES" \
    --strict
  exit $?
else
  echo "error: SwiftLint not found. Please install it using: brew install swiftlint"
  exit 1
fi

7,将这个脚本拖拽到 Compile Sources之前,在编译之前就运行;

8,Command + B,如果代码内有硬编码字符串,应该就会提示报错了。此外如果要修改 .swiftlint.yml文件内的规则,修改规则后务必要先 Clean Build Folder,然后再 Command + B,不然有可能会不生效。

相关推荐
卢叁1 小时前
关于代码优化的一点思考
ios·swift
染指111012 小时前
7.苹果ios逆向-目录结构
ios·ios逆向·苹果·ios目录·苹果目录
shilim21 小时前
这位老哥提交了一个12万行代码的PR,程序员看了都说LGTM
人工智能·github·代码规范
Digitally1 天前
iPhone 恢复出厂设置是否会删除所有内容?
ios·iphone
2501_916007471 天前
iPhone查看App日志和系统崩溃日志的完整实用指南
android·ios·小程序·https·uni-app·iphone·webview
Digitally1 天前
如何将消息转移到新 iPhone
ios·iphone
mit6.8241 天前
[Broken IOS] 配置&CLI | 终端用户界面TUI
c语言·ios·cocoa
大熊猫侯佩1 天前
代码精讲:WWDC 25 @Animatable 宏 —— SwiftUI 动画的新突破
swiftui·swift·wwdc
北_鱼1 天前
设计模式1:创建型模式
java·设计模式·软件工程·代码规范·设计规范
2501_915918411 天前
iOS 抓不到包怎么办?全流程排查思路与替代引导
android·ios·小程序·https·uni-app·iphone·webview