목차

티스토리 뷰

iOS/System

[iOS] SwiftGen 적용하기

Assum 2023. 4. 2. 19:14
728x90
반응형

안녕하세요🐾

앱을 개발하다보면 앱에 사용될 리소스를 필연적으로 에셋 카탈로그(Asstes.xcasset)에 Color, Image 등을 등록하여 사용하게 됩니다.그런데 개발 중 에셋 카탈로그에 존재하지 않는 리소스를 선언하거나 리소스 이름을 오타로 적어 오류나 앱 크래쉬가 난 적이 있으신가요? 전 있었습니다😎 (당당)

 

SwiftGenAsse.xcasset, Localizable.strings 등과 같이 프로젝트에 사용될 각종 리소스를 Swift 코드로 생성해주는 도구입니다.

프로젝트 리소스를 코드로 관리하면 리소스 이름을 잘못쓴다거나 없어진 리소스를 불러오는 등의 상황을 방지할 수 있어 유지보수와 안정적인 측면에서도 많은 도움이 됩니다.

 


 

1. SwiftGen - Install

먼저 깃허브 페이지에 소개된 설치 방법 중 CocoaPod을 이용한 설치를 진행하였습니다.

Podfile을 열어 설치를 진행합니다.

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'SwiftGenTest' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for SwiftGenTest
  pod 'SwiftGen'

end

 

터미널에서 pod install 후 설치가 완료되면 아래의 명령어를 입력합니다.

swiftgen config init

 

 

2. SwiftGen - Setup

실행이 완료되면 Example configuration file created: swiftgen.yml 이라는 문구가 뜨면서 프로젝트 디렉토리에 swiftgen.yml 이라는 파일이 생깁니다. 열어볼까요?

코드화가 필요한 리소스 템플릿을 이곳에서 작성합니다.

주석으로 되어있는 부분들은 예제 코드입니다.

나의 프로젝트에 맞게 수정하여 사용할 리소스 템플릿 코드를 작성해주면 됩니다.

템플릿 코드 예제는 이곳 에서 확인 할 수 있습니다.

 

저는 이 중 문자열, 색상, 이미지를 코드화 하는 템플릿 코드를 작성해보겠습니다.

그전에 먼저 테스트 프로젝트 구조를 살펴볼까요?

테스트를 위해 UtilResources란 폴더를 만들었습니다.

먼저 Util 폴더는 SwiftGen을 설정하고 나면  프로젝트 리소스가 코드화된 클래스 파일이 만들어질텐데요.

그 클래스 파일을 Util 폴더 안에 넣기 위해 만들었습니다.

 

다음으로 Resources 폴더 내엔 이 프로젝트에 사용될 리소스들을 모아넣었습니다.

  • Images.xasset - 이미지 리소스 에셋카탈로그
  • Colors.xasset - 색상 리소스 에셋카탈로그
  • Localizable.strings - 다국어 지원을 위한 .strings 파일

 

이제 위의 상황을 반영한 코드를 swiftgen.yml 파일 내에 작성하면 아래와 같습니다.

# Setup directory
# input_dir - 프로젝트 리소스 경로
# output_dir - 생성될 SwiftGen 클래스 파일 경로
 input_dir: SwiftGenTest/Resources/
 output_dir: SwiftGenTest/Util/


# Generate constants for localized strings.
# inputs의 경로는 input_dir의 후속 경로 입니다.
# outputs는 생성될 클래스 파일의 특성 및 이름을 설정합니다.
 strings:
   inputs:
     - en.lproj
   filter: .+\.strings$
   outputs:
     - templateName: structured-swift5
       params:
         publicAccess: true
         enumName: Strings  # 호출할 enum 이름을 Strings로 변경
       output: Strings+Generated.swift


# Generate constants for Assets Catalogs
# inputs의 경로는 input_dir의 후속 경로 입니다.
# outputs는 생성될 클래스 파일의 특성 및 이름을 설정합니다.
 xcassets:
   inputs:
     - Images.xcassets
     - Colors.xcassets
   outputs:
     - templateName: swift5
       params:
         forceProvidesNamespaces: true
         forceFileNameEnum: true
       output: XCAssets+Generated.swift

 

코드에 대한 간략한 설명은 주석에 달아놓았습니다.

설정이 완료되었으면 한번 실행해볼까요?

터미널 프로젝트 라이브러리 디렉토리에서 아래의 명령어를 입력합니다.

swiftgen

 

실행이 완료되면 아래와 같은 문구가 보입니다.

 

이제 swiftgen.yml에 설정된 output 디렉토리에 가보시면 클래스 파일이 만들어져 있습니다.

이 두놈을 선택하여 Xcode 프로젝트 Util 폴더 내에 드래그하여 집어넣어주시면 됩니다.

 

3. SwiftGen - How to use?

이제 사용 준비가 끝났습니다. 먼저 코드화된 .strings 리소스부터 살펴볼까요?

먼저 Localizable.strings를 보면 Key:Value 형태를 가진 hello_world 문자열 리소스가 하나 선언되어 있는 상태입니다.

 

Util/Strings+Generated 클래스를 열어보면 enum Strings이 보이시죠? 이건 앞전에 swiftgen.yml에 적어놨던 enumName 입니다. 그리고 그 안에 helloWorld라는 리소스가 코드화 되어있는걸 확인 할 수 있습니다.

 

코드화된 프로젝트 문자열 리소스를 코드로 불러오는건 아래와 같이 사용됩니다.  

 

컬러나 이미지 리소스인 경우도 이와 비슷합니다.

Asset이란 enum안에 ColorsImages enum을 하나 더 두어 구분해 접근하도록 되어있는 걸 확인 할 수 있습니다.

 

호출은 아래와 같이 사용됩니다.

 

3.1 SwiftGen - Resource Update

다음으로 프로젝트 리소스를 추가할 땐 어떻게 Uitil 폴더 내에 있는 클래스 파일을 업데이트 해야 할까요?

프로젝트 리소스 추가후 프로젝트 디렉토리에서 아래와 같은 명령어를 입력해주면  업데이트가 이루어집니다.

swiftgen

 

위처럼 프로젝트 리소스를 추가할 때 마다 터미널에서 swiftgen 명령어를 입력하여 사용하여도 큰 지장은 없지만, 갱장히 귀찮겠죠?

프로젝트 빌드시에 위 과정을 수행하는 스크립트를 Xcode에 작성할 수 있습니다!

 

Target - Build Phases - New Run Script Phase 선택

 

생성된 Run Script의 이름을 SwiftGen으로 변경해주겠습니다.

그리고 해당 스크립트 항목을 드래그하여 실행 우선순위를 위로 높여놓았습니다.

 

다음으로 아래와 같이 스크립트 코드를 작성해줍니다.

if [[ -f "${PODS_ROOT}/SwiftGen/bin/swiftgen" ]]; then
  "${PODS_ROOT}/SwiftGen/bin/swiftgen"
else
  echo "warning: SwiftGen is not installed. Run 'pod install --repo-update' to install it."
fi

이제 프로젝트 내 리소스 변경이 있어도 프로젝트 빌드시 Swiftgen 스크립트가 실행되어 리소스 관련 클래스 파일이 업데이트 됩니다.

 

 

3.2 SwiftGen - Detail Use

사견이지만, 코드화된 리소스를 좀 더 직관적으로 사용하고 싶다면 아래와 같은 방법을 사용하시는 것을 추천합니다.

먼저 Image 리소스를 예로 들어볼까요?

 

메인화면온보딩 화면의 상단에 고정되어 표시되는 서로 다른 이미지가 있다고 가정했을 때,

리소스 이름을 어떻게 가져가야 할까요?

- topImage, topImage2...?

 

 

이럴땐 아래처럼 에셋카탈로그 내 폴더를 생성하여 사용되는 이미지의 컨셉이나 UI Flow에 맞춰 구분해주시는게 좋습니다.

 

위와 아래와같은 구조를 만든 뒤 빌드한 후, 아래와 같이 SwiftGen으로 호출해볼까요?

폴더이름 또한 enum으로 구분되어 들어가있는걸 확인 할 수 있습니다.

이러한 구조를 가져가면 추후 유지보수에도 많은 도움이 됩니다. 

 

마지막으로 문자열 리소스는 앱에서 자주 사용되는 단어나 DateFormat과 같은 경우는 아래의 예처럼 마침표를 이용하여 카테고리를 나누면 어떨까요?

 

아래처럼 빌드 후 문자열 관련 리소스 호출해보면 마침표 직전의 문장이 enum으로 구분되어 좀 더 직관적으로 접근 할 수 있습니다.

 

위에 설명드린 방법들 또한 너무 과하 사용하면 지장이 생길 수 있지만 사용하려는 리소스의 대략적인 카테고리를 분류하여 적절히 사용한다면 많은 도움이 될 것같습니다. 

 

긴 글 읽어주셔서 감사합니다. 😎

 

 

4. Reference

- https://github.com/SwiftGen/SwiftGen

- https://github.com/SwiftGen/SwiftGen/blob/stable/Documentation/ConfigFile.md

반응형
댓글
300x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함