SwiftGen 사용기 (Homebrew)

Henry Lee·2022년 1월 19일
0

소개

SwiftGen을 간단하게 소개하자면

이해하기 쉽게 시나리오로 설명을 해보려고 한다.

  • Assets 카탈로그에 Icons, Image, Color등을 정의하고 이를 프로젝트에서 사용하기 위해서는 각각의 생성자 (Color로 예를들자면 UIColor(named:) 를 통해 Asset에 지정한 문자열 상수를 넣어 불러와야 한다.
let customColor = UIColor(named: "customRed")!

해당 방법은 문자열을 하드코딩 한다는 점에서, 실수가 발생할 여지가 있고, 또 런타임에 에러가 결정되기 때문에 컴파일 타임에 해당 실수를 잡아내기 어렵다.

그래서 보완책으로 아래 처럼 사용해볼 수 있었다.

enum Constans: String {
  let customRed = "customRed"
}

extension UIColor {
  static var customRed: UIColor {
    UIColor(named: Constans.customRed.rawValue) ?? UIColor()
  }
}

let customRed: UIColor = .customRed

추가한 에셋이 많을 경우는 매크로 코드를 짜서 일괄로 생성하는 방법도 썼었다.

이 부분을 간편하게 해주도록 나온 것이 바로 SwiftGen이다.
SwiftGen은 위 과정을 템플릿을 통해 일괄적으로 작업할 수 있게 해주고,
하드코딩에 의한 실수, 또 컴파일 타임에 에러를 잡을 수 있도록 도와준다.
어떻게 사용하는지 알아보자.

설치

설치 전에 나의 작업 환경은 다음과 같다.
1. m1 macbook pro 16g
2. Xcode 13.2
3. Monterey 12.1

설치 방법
github에 잘 소개 되어있기도 한데 여러 방법마다 장단이 있는 것 같다.
1. Download the ZIP
2. CocoaPods
3. Homebrew
4. Mint
Zip과 CocoaPods는 프로젝트 별로 따로 적용하는데 이용하기 편하고
Homebrew와 Mint는 시스템 전체적으로 사용할 수 있기 때문에,프로젝트 마다 일일이 설정하기 싫은 경우 선택할 수 있다.

나는 Homebrew를 선택했고, Homebrew로 설치했지만, 프로젝트마다 다르게 swiftgen.yml을 다르게 적용해보려고 한다.

Homebrew 설치

terminal에서 brew로 swiftgen을 설치한다.

brew update
brew install swiftgen

이 경우 hoem directory에 기본적으로 swiftgen.yml이 위치하게 된다.

swiftgen 기본 사용법

swiftgen의 기본 사용 방법은 swiftgen.yml을 통해 템플릿을 작성하고
swiftgen으로 템플릿을 파싱하는 식이다.

swiftgen.yml에서는 번들의 Assets.xcassets를 파싱해서
Asset+Generated.swift(예시 이름)를 생성한다.

Asset+Generated.swift에는 열거형으로 Asset에 정의한 것들을 접근할 수 있게 한다.
예를들어

let customRed: UIColor = Asset.Color.customRed.color

위와같이 쓸 수 있다. 타입 어노테이션은 참고하라고 써둔 것이고 필수가 아니다.

일단은 저게 어떻게 돌아가는지 간단하게 테스트 해보자.

터미널에서 다음과 같이 입력한다.

cd ~/Desktop
swiftgen config init

만약 여기서 에러 났으면 brew로 swiftgen이 설치가 안된거다.

우선 사용하기 편하게 데스크톱 디렉토리로 이동 한 뒤 작업한다.
위 명령어는 swiftgen.yml을 생성하는 명령어이다.
Dekstop 디렉토리로 가면 swiftgen.yml이 생성되어 있을 것이다.
아마 swiftgen config init 명령어를 입력하면 swiftgen.yml 파일이 자동으로 편집기로 열릴 것이다.

swiftgen.yml내용을 보면 주석으로 사용법이 자세하게 적혀있는게 나중에 디테일 하게 사용하고 싶다면 꼭 읽어보자

우리는 우선 asset에만 집중해보자.

  • 프로젝트에서 방금 만든 swiftgen.yml을 가져오자.

릴리즈 하고 나면 swiftgen이 실행 될 일이 없기 때문에, 따로 가져올 필요가 없지만, 설명에 편의를 위해 가져왔다. 프로젝트에 따로 추가하지 않아도 되고 필요한 디렉토리 위치시켜 두고 위치만 지정하면 된다.

yml내용을 보면

# xcassets:
#   inputs:
#     - Main.xcassets
#     - ProFeatures.xcassets
#   outputs:
#     - templateName: swift5
#       params:
#         forceProvidesNamespaces: true
#       output: XCAssets+Generated.swift

이 부분이 Asset을 파싱 후 컨버팅 해주는 부분으로, 조리해서 사용하면 된다.

사용해보려고 하는 부분은 Color Asset을 별도로 만들어 볼려고 한다.

Asset Catalog를 하나 새로 만든다.

이름은 Color 로

Color Asset안에 커스텀 컬러 몇개 저장 후

swiftgen.yml에 다음과 같이 내용을 추가한다.

xcassets:
  inputs:
    - Color.xcassets
  outputs:
    - templateName: swift5
      params:
        enumName: Colors
      output: Color+Generated.swift

내용을 찬찬히 뜯어보면

  • xcassets: xcassets 형태를 파싱하기 위한 명령어로 문서보면 xcassets말고도 string, ib 등등이 있다.
  • inputs: 입력할 파일로 우리가 생성한 Asset Catalog를 전달
  • outputs: 출력할 영역
    - templateName: swift5를 쓰자, 특별히 swift4를 쓸일이 있으면 해당 내용을 전달하면 된다. 자세한 내용은 문서
    • params: 파일을 출력할 때 몇가지 옵션을 줄 수 있다.
    • enumName: 따로 설정하지 않으면 기본 열거형의 이름이 Asset로 정해진다.
    • output: 출력할 파일 이름

작성이 끝났으면 terminal로 해당 yml이 있는 디렉토리로 찾아간다.
그리고 아래 명령어를 입력
swiftgen config run
성공적으로 명령어가 동작했다면
File written: Color+Generated.swift
이라고 표시된다.
지금은 아무것도 보이지 않을텐데 해당 디렉토리로 가 보면
Color+Generated.swift파일이 생성 되어 있을 것이다.
이를 프로젝트에 추가한다.

struct ContentView: View {
  var body: some View {
    Text("Hello, world!")
      .padding()
      .foregroundColor(Colors.customRed.color)
  }
}
extension View {
  func foregroundColor(_ uicolor: UIColor) -> some View {
    self.foregroundColor(Color(uicolor))
  }
}
  • extension은 foregroundColor에서 UIColor로 바로 생성할 수 있도록 작성 된것

실제로 컬러는
Color.customRed.color로 접근할 수 있다. 형태는 Color는 yml에서 작성한 enumName이다.

여기까지가 기본적인 작업 플로우로, 정리해보면

  • swiftgen.yml 을 생성
  • swiftgen.yml 템플릿 내용을 작성
  • terminal에서 swiftgen config run
  • 생성된 swift파일 프로젝트에 추가
    이다.

여기서 좀더 생각해보면, Asset Catalog에 새 Asset이 추가될 때 마다 terminal 키고 swiftgen config run 하면 너무 귀찮은데? 라는 생각이 들 수 있다. 이부분을 자동화 시켜줄 수 있는것이 바로 Run Script이다.

RunScript

프로젝트 -> 타겟 -> 빌드 페이즈(Build Phases)로 이동한 뒤
Run Script를 하나 추가하자.

run script는 빌드 할 때 자동으로 터미널 켜서 스크립트 안에 적힌 내용을 실행시켜 주는 기능이라고 생각하면 된다.


요 Shell 안에 내용을 작성할 것인데

여기서 앞서 우리가 터미널에서 했던
swiftgen config run 을 작성해주면
빌드 될 때 마다 파싱해서 Generated.swift를 생성해 줄 것이다.


위 내용을 넣고 빌드해보면~

에러가 난다.
별 내용은 아니고 terminal에서 swiftgen 실행시키려고 하는데 없어서 그러는 거다.
brew에 설치된 swiftgen을 실행시켜야 해서 패스를 지정해 준다.

PATH=/opt/homebrew/bin:$PATH
swiftgen config run

여기서 실행 시켜보면 또 에러가 난다.

이번에는 swiftgen.yml을 찾을 수가 없다고 나온다. 엥?
그래서 해당 명령어를 실행하기 전에 위치한 디렉터리가 어딘지 보자

PATH=/opt/homebrew/bin:$PATH
pwd
ls
swiftgen config run

스크립트에 위 내용으로 변경후 발생하는 에러를 보면

프로젝트 폴더에는 가있는데 타겟 폴더에 안들어가 있다.

타겟 폴더 안으로 들어가면 되겠다.

PATH=/opt/homebrew/bin:$PATH
cd SwiftGenPractice
swiftgen config run

이제 빌드해보면 에러가 발생하지 않고 정상 빌드 될 것이다!

인라인?

이 경우는 swfitgen.yml을 찾고 내용대로 파싱해서 파일을 생성하는 방식인데 사실 예제처럼 파싱할 내용이 많지 않으면 yml없이 인라인으로 작성할 수도 있다.

swiftgen xcassets Resources/Images.xcassets --templateName swift5 --output "Constants/Assets+Generated.swift"

정리

  1. swiftgen은 자동화 도구로 사용만 잘하면 굉장히 유용하다.
  2. 굳이굳이 homebrew로 설치하고, 프로젝트 마다 다르게 사용하려면 위 처럼 고생한다. 잘 동작은 하는데 이게 맞는 방법인지는 모르겠다.
  3. 템플릿을 커스텀하거나, 파싱하는데 더 다양한 옵션을 제공하므로 문서를 꼭 확인하자.
    전체코드
profile
iOS Dev, Coffee in my bloodstream

0개의 댓글