본문 바로가기
Swift/기초

Swift | Swift Lint 이해하기(feat. 면접)

by UDDT 2025. 12. 3.

들어가며.. 

     면접을 보던 중 Swift Lint에 대한 이야기를 들었습니다

    "작성한 코드 중에 개행 문자가 일치가 잘 안되는 부분이 있네요? SwiftLint를 사용해보셔도 좋았을거 같아요" 

    면접관님께 "돌아가서 부족한 부분을 채우겠다"고 말씀드리기도 했고,

    Swift Lint는 키워드로만 알고 있었어서 사용법과 함께 간단한 정리를 해보려고 합니다

 Swift Lint란

     Swift Lint는 Swift 코드 스타일과 관련된 정적 분석 도구입니다

    조금 과장하자면, 일정한 규칙을 가진 작은 컴파일러를 하나 더 만든다고 생각하시면 됩니다

 

    Swift Lint는 한국어 ReadMe도 있기 때문에, 다른 라이브러리에 비해 비교적 쉽게(?) 적용해볼 수 있습니다

    https://github.com/realm/SwiftLint/blob/main/README_KR.md

 

SwiftLint/README_KR.md at main · realm/SwiftLint

A tool to enforce Swift style and conventions. Contribute to realm/SwiftLint development by creating an account on GitHub.

github.com

 

    에러 없이 바로 적용하고 싶으신 분은, SPM으로 바로 넘어가주세요

 Swift Lint가 왜 필요한데?

    협업을 하다보면, 다양한 협업 규칙이 생겨납니다

1. Class를 선언할 때 내부 코드 작성 전 개행은 1개만 하자
2. 줄 길이는 120자를 넘기지 말자
3. 강제 언래핑은 사용하지 말자
4. 미사용하는 import는 정리하자
.
.

    

    개인이 아닌 팀프로젝트를 기준으로 했을 때, '좋은 코드'란 무엇일까요?

   팀의 컨벤션이 잘 지켜진 코드도 그 중 하나일 것 같습니다

   Swift Lint는 바로 이 지점에서 필요합니다

 

   PR을 할 때마다 일일히 "공백 줄 이상해요", "줄 길이가 너무 길어요", "인덴트 달라요" 하는 대신,

   Tool로써 lint를 사용하고 규칙을 먼저 체크해주는 것도 개발자의 피로도를 낮춰줄 수 있습니다

 Swift Lint 설치하기

    Swift Lint는 brew 또는 CocoaPods으로 설치할 수 있습니다(저는 하기의 오류들로 인해 SPM 방식을 사용했습니다)

   저는 brew를 기준으로 설치해보겠습니다

   설치 방법은 간단합니다

brew install swiftlint

 

   터미널에서 다음과 같은 명령어를 입력하면 됩니다

프로젝트에 SwiftLint 적용하기

   Project - TARGETS - BuildPhase에서 + 버튼을 누르고 New Run Script Phase를 선택합니다

 

    그 후 Run Script 안에 하기의 내용을 추가하면 됩니다

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

 

   이 내용을 추가하면 Navigator 영역(⌘ + 9)에서 다음과 같은 에러를 만날 수 있습니다  

 

   애플 실리콘 환경에서 lint를 설치했기 때문에, 경로를 읽어오지 못합니다

 

   ReadMe에 있는 가이드에 따라서 스크립트를 다음과 같이 바꿔줍니다(빌드 에러가 발생합니다)

if [[ "$(uname -m)" == arm64 ]]; then
    export PATH="/opt/homebrew/bin:$PATH"
fi

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

 

   가이드대로 했는데, 빌드 에러가 납니다

 

  로그에 나와 있는대로, Based on dependency analysis를 꺼줍니다

 

   문제가 해결되지 않습니다

 

  에러 로그를 보면,

 SwiftLint가 검사 대상이 되는 Swift 파일을 못 찾은 것처럼 보입니다

 User Script Sandboxing을 No로 설정하면 Build가 됩니다 

 

  왜 이런 오류가 발생했을까요?

  User Script Sandboxing이 켜져있어서, swiftLint가 특정 프로젝트의 루트를 읽을 수 없다는 오류입니다

  Xcode 15부터는 User Script Sandboxing에 따라 Run Script에서 Input files / Output files에 선언한 경로만 읽을 수 있습니다

  User Script Sandboxing은 스크립트 단계가 소스 파일이나 중간 빌드 객체에 액세스하는 것을 차단할지에 대한 여부를 결정합니다

  이 설정을 NO로 바꾸게 되면, 

  Run Script가 샌드박스 밖에서 실행되는 것처럼 동작해서 swiftLint가 내부 파일을 자유롭게 읽을 수 있게 됩니다

  다만 User Script Sandboxing은 Apple에서 권장하는 방식은 아닙니다 

  샌드박스를 끄면, 잠재적으로는 보안/안정성 측면의 이점을 포기하는 셈이 됩니다

 그러면 어떻게 이 문제를 해결해볼 수 있을까요?

SPM으로 안전하게 SwiftLint 세팅하기

    Xcode 15+에서는 Run Script 대신 SPM의 Build Tool Plugin을 쓰는 방식으로 이를 해결해볼 수 있습니다

  

     둘다 None으로 설정하고, Add Package를 눌러줍니다

  TARGETS - Build Phases - Run Build Tool Plug-ins에서 + 버튼을 눌러줍니다 

 

     SwiftLintBuildToolPlugin을 Add해줍니다

 

        add 후에 최초 빌드를 하면 다음과 같은 Waring이 나올 수 있습니다

 

        첫번째 에러는 SwiftLint 패키지 안에 SwiftLintCoreMacros의 사용을 허용하지 않아서 뜨는 오류라서,

      아래의 Trust & Enable을 클릭해주면 됩니다

 

          두번째 에러도 비슷한 플로우인데, SwiftLintBuildTooPlugin을 사용한다고 해주지 않아서 뜨는 에러입니다

       마찬가지로 Trust & Enable을 클릭해주면 됩니다

 

      적용만 잘 되었다면, User Sandbox 설정을 건드리지 않고도 정상 빌드가 됩니다

 

 SwiftLint 규칙 

// 스타일 관련
line_length    // 한줄 길이 제한(100~120으로 설정)
trailing_whitespace     // 줄 끝에 공백이 있으면 경고
vertical_whitespace   // 빈줄을 1줄까지만 허용
vertical_whitespace_between_cases       // switch case 사이 공백 관리
opening_brace        // { 앞뒤 공백 규칙, 줄바꿈 규칙)
colon        // let foo: Int 처럼 콜론 앞뒤 공백
trailing_newline    // 파일 마지막에 빈 줄 하나 필수

// 위험 | 안티 패턴 관련
force_cast (as!)
force_try (try!)
force_unwrapping (! 옵셔널 강제 해제)

// 사용하지 않는 코드 관련
unused_optional_binding
unused_closure_parameter  // _ in 으로 바꾸라고 경고
unused_import      // 사용하지 않는 import 정리하라고 경고

// 네이밍 | 구조 관련
identifier_name      // 너무 짧은 변수명 금지(a, b, c) + 예외 리스트
type_name        // 타입 이름 길이, 대문자 시작 여부 등
file_length     // 파일 길이 제한
type_body_length    // 타입 길이 제한
function_body_length      // 함수 길이 제한
nesting         // if, switch, closure가 너무 깊게 중첩되는 것 제어

 

    위의 규칙 외에도 다양한 규칙이 있습니다

   github에서 확인하거나 terminal에서 swiftlint rules 명령어를 입력해서 확인할 수 있습니다

  https://github.com/realm/SwiftLint/tree/main/Source/SwiftLintBuiltInRules/Rules

 

SwiftLint/Source/SwiftLintBuiltInRules/Rules at main · realm/SwiftLint

A tool to enforce Swift style and conventions. Contribute to realm/SwiftLint development by creating an account on GitHub.

github.com

 

 SwiftLint 규칙 적용하기

    SwiftLint에서 규칙을 적용하려면, .swiftLint.yml 파일이 필요합니다

  Empy file을 만들고, 파일명을 .swiftLint.yml로 설정합니다

 

   Next를 누르면 .으로 시작하는 숨김파일을 만들 수 있습니다

 

     이제 여기 내부에 규칙을 작성해주면 됩니다(하기는 작성 예시)

# 1. 끄고 싶은 규칙
disabled_rules:
  - trailing_whitespace    #줄 끝 공백은 신경 쓰지 않는다
  - todo                   #TODO 경고 끄기
  - identifier_name

# 2. opt-in 규칙 (기본이 off인데, on할 규칙들)
opt_in_rules:
  - opening_brace
  - force_unwrapping
  - unused_import
  - vertical_whitespace
  - file_length

# 3. 분석 대상 / 제외 경로
included:
  - LintTeset1      # 프로젝트 소스 폴더
# - LintTest1/ViewController.swift       #등 구체적으로 작성도 가능

# 4. 각 규칙별 커스터마이징 예
line_length:
  warning: 120
  error: 200

trailing_whitespace:
  ignores_empty_lines: true
  ignores_comments: true

vertical_whitespace:
  max_empty_lines: 1

 

     이러한 규칙을 적용한 상태에서 테스트를 해보면,

    다음과 같이 잘 적용이 되었음을 확인할 수 있습니다

 

 결론 

    SwiftLint의 성능 이슈를 걱정할 수는 있겠지만,

   생각해보면 SwiftLint 자체가 빌드 타임에 검사하는 도구라서 앱 런타임 자체의 성능에 영향을 주지는 않습니다

   다만, 프로젝트가 커지거나 규칙이 많아진다면 lint가 소모하는 시간(빌드시간)이 길어지기 때문에

   꼭 필요한 규칙만 켜는 것이 중요할 것 같습니다

 

    SwiftLint 없이도 협업 규칙을 잘 지켜지고 있다면 그 자체로 이미 좋은 팀입니다.

   하지만 새롭게 합류하는 사람도 빠르게 팀 스타일에 적응해야 하거나,

   리뷰어가 '공백, 줄 길이' 같은 것에 시간을 덜 쓰게 하고 싶다면

   미리 SwiftLint를 도입하는 것도 많은 도움이 될 것 같습니다

   

최근댓글

최근글

skin by © 2024 ttuttak