SwiftGen은 자동으로 코드 및 파일을 자동으로 만들어줍니다.!! 알아두고 익혀두면 편리해요~
- SwiftGen : 어떻게 사용하는 것일까요? 라이브러리 링크는 클릭하시면 됩니다.
- auto-generate 됩니다. 즉, 자동으로 소스를 변경/생성해주어서 작업 노가다?를 줄이면서 타입의 안정성을 보장해 주는 도구입니다.
| 버전 정보를 보니 특별한 것이 있습니다. 하나의 라이브러리에 3가지 라이브러리 정보가 표시가 되네요. !!!
$ swiftgen --version
SwiftGen v5.2.1 (Stencil v0.9.0, StencilSwiftKit v2.3.0, SwiftGenKit v2.1.1)
- Stencil : 스텐실은.. magical!, reusable!! 이라 하네요. 매직컬하게 재사용이 가능한 웹 컴퍼넌트 컴파일러라고 합니다.
- StencilSwiftKit : Swift 코드 생성 전용 스텐실 노드와 필터들을 추가로 가져 오는 프레임 워크입니다.
- SwiftGenKit : SwiftGen의 프레임 워크로 다양한 리소스를 분석해서 스텐실 컨텍스트로 변환합니다.
- 이 저장소는 기본 SwiftGen 저장소에 병합되었다고 합니다.
link를 클릭해서 "Install"부분을 하세요. 간단하게는 아래의 내용대로 하시면 됩니다.
ex)
설치
$ brew update
$ brew install swiftgen
확인
$ swiftgen --version
우선 기본 템플릿으로 만들어 보며 사용법을 익혀보고, 그 이후에 스텐실을 이용해서 내가 원하는 템플릿 파일을 만드는 방법에 대해 알아보려고 합니다.
샘플 소스를 다운로드하고 "/Resources/TestCase0?Localizable.strings"파일을 수정하십시오. 그런 다음 빌드를 실행하십시오. 그러면 "/Constants/Test.Case0 ?.Localized.swift"파일이 변경됩니다.
- 여러 케이스를 만들었습니다. 위의 예시는 첫번째 경우에요. Resources 가 되는 부분의 내용을 수정해보거나, 결과 파일을 실제 폴더에서 지우고 빌드도 해보며, 자동 생성되는 것을 알아봅시다.
Script 셋팅 방법 (Target >> Bulid Phases Tap >> + Button Click >> New Run Script Phase) |
기본 제공되는 템플릿을 여기서 셋팅했습니다. |
---|---|
- "****.sh" 파일을 생성해서 그것을 실행 시키게 한다든지.. 다양한 방법이 있습니다.
- 기본적으로 SwiftGen은 5가지 제공되는 템플릿이 있습니다.
- 스트링(혹은 로컬라이제이션) : swiftgen strings [OPTIONS] FILE1 …
- 스토리보드 : swiftgen storyboards [OPTIONS] DIR1 …
- xcassets에 설정한 것들(주로 이미지) : swiftgen xcassets [OPTIONS] CATALOG1 …
- 색상정보 : swiftgen colors [OPTIONS] FILE1 …
- 추가한 폰트 : swiftgen fonts [OPTIONS] DIR1 …
개별 테스트한 경우는 스크롤 하시면 더~ 아래에 하나씩 설명이 있습니다.
- ViewController.swift
- 만들어진 결과물로 아래와같은 코드로 나타내어 봤습니다.
override func viewDidLoad() {
super.viewDidLoad()
testSamplesBaseTemplates()
}
func testSamplesBaseTemplates() {
// Case 01 : String
case01Label.text = L10n.testCase01TitleTop01
// Case 02 : String
case02Label.text = TestCase02Strings.testCase02TitleTop01
// Case 03 : String
case03Label.text = TestCase03Strings.testCase03TitleBottom01
// Case 04 : Storyboard
// Pass
// Case 05-1 : Assets
// let swiftGenSample01Image = UIImage(asset: Asset.imageSwiftGenSample01)
let swiftGenSample01Image = Asset.imageSwiftGenSample01.image
case0501ImageView.image = swiftGenSample01Image
debugPrint(Asset.allImages)
// case0502Label.textColor = UIColor(asset: Asset.test01Color)
case0502Label.textColor = Asset.test01Color.color
debugPrint(Asset.allColors)
// Case 06 : Colors
// case06Label.textColor = Color(named:ColorName.articleBody)
case06Label.textColor = ColorName.articleBody.color
// Case 07 : Fonts
// case06Label.font = UIFont(font: FontFamily.SFCompactDisplay.ultralight, size: 30.0)
case07Label.font = UIFont(font: FontFamily.SFProDisplay.blackItalic, size: 30.0)
}
자세한 내용을 살펴볼까요?
TestCase01Localizable.strings을 셋팅하고 기본적인 스크립트를 실행했습니다.
- resource file : TestCase01Localizable.strings
Script.. # testing script case 01 swiftgen strings "${SRCROOT}/${TARGETNAME}/Resources/TestCase01Localizable.strings" --template structured-swift4 --output "${SRCROOT}/${TARGETNAME}/Constants/BasicTemplate/Test.Case01.Localized.swift"
Link(SwiftGen)에서 "Templates bundled with SwiftGen:" 부분을 읽어보세요.
테스트는 swift 4로 했습니다.
A swift2 template, compatible with Swift 2 A swift3 template, compatible with Swift 3 A swift4 template, compatible with Swift 4 Other variants, like flat-swift2/3/4 and structured-swift2/3/4 templates for Strings, etc.
- file link : .. /Constants/BasicTemplate/Test.Case01.Localized.swift
열거 형의 이름을 직접 정의하고 커멘드를 좀 줄여보았습니다.
- 추가된 부분 : --param enumName=TestCase02Strings
- 수정된 부분 1 : --output => -o
- 수정된 부분 2 : --template => -t
Script.. # testing script case 02 swiftgen strings --param enumName=TestCase02Strings "${SRCROOT}/${TARGETNAME}/Resources/TestCase02Localizable.strings" -t structured-swift4 -o "${SRCROOT}/${TARGETNAME}/Constants/BasicTemplate/Test.Case02.Localized.swift"
- file link : .. /Constants/BasicTemplate/Test.Case02.Localized.swift
localization 설정을 해볼까요? 이것도 잘되는 지 확인해봅니다.
- modify : ../Resources/.. => ../Resources/Base.lproj/..
difference point |
---|
Script.. # testing script case 03 swiftgen strings --param enumName=TestCase03Strings "${SRCROOT}/${TARGETNAME}/Resources/Base.lproj/TestCase03Localizable.strings" -t structured-swift4 -o "${SRCROOT}/${TARGETNAME}/Constants/BasicTemplate/Test.Case03.Localized.swift"
- file link : .. /Constants/BasicTemplate/Test.Case03.Localized.swift
스토리 보드는 약간 다르지만 비슷합니다.
Script.. # testing script case 04 swiftgen storyboards -t swift4 "${SRCROOT}/${TARGETNAME}/Base.lproj/Main.storyboard" -o "${SRCROOT}/${TARGETNAME}/Constants/BasicTemplate/Test.Case04.Storyboards.swift"
- file link : .. /Constants/BasicTemplate/Test.Case04.Storyboards.swift
이번에는 Xcassets을 테스트 해볼까요?
Script.. # testing script case 05 swiftgen xcassets "${SRCROOT}/${TARGETNAME}/Assets.xcassets" -t swift4 -o "${SRCROOT}/${TARGETNAME}/Constants/BasicTemplate/Test.Case05.Xcassets.swift"
- file link : .. /Constants/BasicTemplate/Test.Case05.Xcassets.swift
셈플 컬러 파일을 아래와 같이 추가했습니다. 물론 "xcassets" 안에 컬러를 추가할 수도 있어요. 앞에 케이스에서 New Color를 하면 되고, 실제로 하나 추가해봤어요. 그 부분도 Case 05 결과를 보실때 확인해 보셔요~
- 파일 추가 (colors.txt)
add colors.txt |
---|
Script.. # testing script case 06 swiftgen colors -t swift4 "${SRCROOT}/${TARGETNAME}/Resources/colors.txt" -o "${SRCROOT}/${TARGETNAME}/Constants/BasicTemplate/Test.Case06.Colors.swift"
- file link : .. /Constants/BasicTemplate/Test.Case06.Colors.swift
Apple의 글꼴 파일 중 일부를 추가하였고, 해당 경로의 글꼴을 파일로 코드 생성하려고 했습니다. 진행사항입니다.
- 추가한 폰트 파일 ("Font" 폴더 안에 넣었습니다.)
폰트 파일 추가 |
---|
Script.. # testing script case 07 # https://developer.apple.com/fonts/ swiftgen fonts -t swift4 "${SRCROOT}/${TARGETNAME}/Resources/Font" -o "${SRCROOT}/${TARGETNAME}/Constants/BasicTemplate/Test.Case07.Fonts.swift"
- file link : .. /Constants/BasicTemplate/Test.Case07.Fonts.swift
이제 우리 개발자가 원하는 포멧으로 수정해볼까요?
- Stencil은 무엇입니까? : https://stencil.fuller.li/en/latest/
The Stencil template language Stencil is a simple and powerful template language for Swift. It provides a syntax similar to Django and Mustache. If you’re familiar with these, you will feel right at home with Stencil.
- 사용법 만 알아두면 스텐실을 기본적으로 사용할 수 있습니다.
- 아래의 테스트 케이스를 살펴 볼까요?
- 문법은 스크립트라 개발자 이시라면 생각보다 어렵지 않으실 것입니다.
- 그리고 저의 접근은 아래 링크를 이용해서 수정하는 것입니다.
- SwiftGen의 기본 템플릿을 생성하는 스텐실 파일들이 들어있습니다. 그 안의 파일을 하나 가져와서 그걸 기반으로 조금씩 조금씩 제거하거나 다른 내용을 넣어보면서 테스트 해보면, 접근하기 쉬울 것입니다.
Objective-C에서 필요한 파일을 만들 수 있을까요? 확장자가 ".h"이며 #define 으로 정의된 내용들이 있는 파일을 만들어보고 싶었습니다. 가능할까요?
- 시도해보겠습니다. :)
Script.. # testing script case 01 swiftgen strings "${SRCROOT}/${TARGETNAME}/Resources/TestCase01Localizable.strings" --templatePath ${SRCROOT}/swiftgen/StencilTemplates/Localization/objLocalization.stencil --output "${SRCROOT}/${TARGETNAME}/Constants/CustomTemplate/Test.Custom.Case01.Localized.h"
- flat-swift4.stencil : 수정전 참고한 파일
- objLocalization.stencil : 생성한 파일
{% if tables.count > 0 %} {# You can modify the value below with the actual value. #} {% macro recursiveBlock table item sp %} {{sp}} {% for string in item.strings %} {{sp}} {% if not param.noComments %} {{sp}} /// {{string.translation}} {{sp}} #define {{string.name}} "{{string.key}}" {{sp}} {% endif %} {{sp}} {% if not param.noComments %} {{sp}} /// LOG : {{string}} {{sp}} {% endif %} {{sp}} {% endfor %} {% endmacro %} {# print #} {% call recursiveBlock tables.first.name tables.first.levels "" %} {% else %} // No string found {% endif %}
-
file link : .. /Constants/CustomTemplate/Test.Custom.Case01.Localized.h
-
아래와 같습니다.
/// test(case01) string 1 #define test_case01_sub_index01 "test_case01_sub_index01" /// LOG : ["translation": "test(case01) string 1", "name": "test_case01_sub_index01", "key": "test_case01_sub_index01"] /// test(case01) string 2 #define test_case01_sub_index02 "test_case01_sub_index02" /// LOG : ["translation": "test(case01) string 2", "name": "test_case01_sub_index02", "key": "test_case01_sub_index02"] /// test(case01) sample 2 #define test_case01_title_bottom01 "test_case01_title_bottom01" /// LOG : ["translation": "test(case01) sample 2", "name": "test_case01_title_bottom01", "key": "test_case01_title_bottom01"] /// test(case01) sample 1 #define test_case01_title_top01 "test_case01_title_top01" /// LOG : ["translation": "test(case01) sample 1", "name": "test_case01_title_top01", "key": "test_case01_title_top01"]
- 충분히 해볼만 합니다.
기본 템플릿을 보다 다르게 보이게 하려 합니다. 흠.. 무엇을 만들어 볼지 생각해보지 못했네요.
.. 편리한 것을 만들어보려 합니다. (생각중.. 고민중.. 뭘 만들어보지..)
현재 앞서가는 개발업체들은 SwiftGen을 이용해서 개발 효율을 높이고 있는 것 같습니다. 한번 사용해 보시면 어떨까요?
만약 빌드때 느리다면, 빌드시점에서 스크립트가 실행되도록 하지말고, 수정이 있을 때 마다(혹은 필요시) 별도로 쉘에서 스크립트 명령어로 실행하는 식으로 관리할 수도 있습니다. 어짜피 자산 파일들은 자주 변경되는 부분은 아니니깐요.
- iOSSampleApp 이런 식으로 하나의 프로젝트 단위 패키지가 가능합니다.
- 감사합니다.
- 시간이 되면 조금더 셈플을 만들어 보겠습니다.