Git, CocoaPods, Xcode, Shell
[iOS - swift] Xcode 코드 템플릿 (File Template, Custom File Template)
jake-kim
2021. 11. 15. 01:27
Xcode File Template
- 파일을 생성할 때 기존에 정의한 Template에 따라 생성되는 로직
- 아래의 경로로 이동하면 기존의 template들을 확인 가능
cd /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/
- `open .` 실행하면 아래 디렉토리 오픈
ex) 파일 템플릿 - Unit Test Case Class
Template 생성 방법
- Custom Template은 위 위치에다가 놓지 않고 다른 경로에 추가하여 연동
- 아래 경로에 Templates폴더와 그 하위에 File Templates 폴더를 생성
cd ~/Library/Developer/Xcode
- Templates폴더, File Templates 폴더 생성
mkdir -p ~/Library/Developer/Xcode/Templates/File\ Templates
- 해당 디렉토리에 .xctemplate 폴더를 만들고 template생성에 필요한 것들을 삽입
- jake 템플릿 생성
mkdir -p ~/Library/Developer/Xcode/Templates/File\ Templates/jake.xctemplate
- jake.xctemplate에 필요한 파일들은, 기존것을 복사하여 수정하면 편하므로, Unit Test Case Class 템플릿 4개 파일 복사
- TemplateIcon-1016.png
- TemplateIcon-1016@2x.png
- TemplateInfo.plist
- ___FILEBASENAME___.swift
cd /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/'File Templates'/ios/source/'Unit Test Case Class.xctemplate'
(위 경로로 이동이 안될경우에는 아래 명령어 실행)
cd
cd /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/'File Templates'/iOS/Source/'Cocoa Touch Class.xctemplate'
- jake.xctemplate 폴더에 붙여넣기
(jake 템플릿 위치)
cd ~/Library/Developer/Xcode/Templates/File\ Templates/jake.xctemplate
- 프로젝트를 열어서 새 파일을 생성 cmd+N 하고 jake template 확인
Template 구현
- 붙여넣기한 ___FILEBASENAME___.swift 파일을 열어서 수정
- 아래 내용으로 변경
//___FILEHEADER___
import UIKit
class ___FILEBASENAMEASIDENTIFIER___: BaseViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
- TemplateInfo.plist 파일 수정
- plist 정보
- Kind: 템플릿 종류
- Description, Summary: 설명
- SortOrder: Template간에 어떤게 먼저 나오는지 순서 결정 ()
- BuildableType: 해당 값은 Template을 통해 파일을 만들 때 Targets이 test로 되어있게 디폴트 설정 값
- DefaultComletionName: 해당 template file을 만들때 미리 입력되어 있는 이름
- Options: 해당 값은 아래에서 설명이 나오므로 일단 삭제
- 수정 완료
- jake 템플릿 로드
- plist에서 DefaultComletionName을 VC로 했기 때문에 VC가 입력되어 있는 상태
- plist에서 BuildableType값을 지웠으므로 Targets이 본 프로젝트로 디폴트 적용 (BuildableType = test면 )
TemplateInfo.plist의 Option 사용 방법
- Option 기능: Template 생성 시 사용자에게 입력하게하여 템플릿 생성
- plist파일을 code로 불러오기 위해서 vscode로 오픈
- 해당 코드 복붙
<key>Options</key>
<array>
<dict>
<key>Identifier</key>
<string>productName</string>
<key>Required</key>
<true/>
<key>Name</key>
<string>Model:</string>
<key>Description</key>
<string>The name of the Model, View and ViewModel to create</string>
<key>Type</key>
<string>text</string>
<key>Default</key>
<string>MyModel</string>
</dict>
</array>
- 다시 template 생성하면 바로 파일을 만드는화면이 아닌 Option화면이 표출
-VC, -VM, -Builder 세 가지 파일 동시에 만들기
> jake.xctemplate 폴더를 프로젝트 폴더에 생성
> 파일은 아래 파일을 복붙하여 수정
cd /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/'File Templates'/ios/source/'Unit Test Case Class.xctemplate'
> Template을 이용하여 Home을 입력하면, HomeVC, HomeVM, HomeBuilder 세 가지 파일이 동시에 만들어지도록 설정
- .swift파일 세 개 준비
- 주의 사항
- ___FILEBASENAME___Builder.swift: 파일 이름 (Home으로 생성 시 각 파일에서 HomeBuilder, HomeVC, HomeVM 값)
- ___VARIABLE_productName:identifier___: 입력당시의 이름 (Home으로 생성 시 각 파일에서 "Home" 값)
//___FILEHEADER___
import Foundation
class ___FILEBASENAMEASIDENTIFIER___ {
static func build() -> ___VARIABLE_productName:identifier___VC {
let dependencies = ___VARIABLE_productName:identifier___VMImpl.Dependencies()
let vm = ___VARIABLE_productName:identifier___Impl(dependencies: dependencies)
return ___VARIABLE_productName:identifier___VC.instantiate(viewModel: vm)
}
}
- ___FILEBASENAME___VC.swift
//___FILEHEADER___
import UIKit
import RxSwift
import RxCocoa
import SnapKit
class ___FILEBASENAMEASIDENTIFIER___: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
- ___FILEBASENAME___VM.swift
//___FILEHEADER___
import Foundation
protocol ___VARIABLE_productName:identifier___VMInput {
}
protocol ___VARIABLE_productName:identifier___VMOutput {
}
protocol ___VARIABLE_productName:identifier___VM: ___VARIABLE_productName:identifier___VMInput, ___VARIABLE_productName:identifier___VMOutput {}
class ___VARIABLE_productName:identifier___VMImpl: ___VARIABLE_productName:identifier___VM {
}
- plist파일
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string></string>
<key>SupportsSwiftPackage</key>
<true/>
<key>Kind</key>
<string>Xcode.IDEFoundation.TextSubstitutionFileTemplateKind</string>
<key>Description</key>
<string>A class implementing ViewController</string>
<key>Summary</key>
<string>A class implementing ViewController</string>
<key>SortOrder</key>
<string>11</string>
<key>DefaultCompletionName</key>
<string>VC</string>
<key>Platforms</key>
<array>
<string>com.apple.platform.iphoneos</string>
</array>
<key>Options</key>
<array>
<dict>
<key>Identifier</key>
<string>productName</string>
<key>Required</key>
<true/>
<key>Name</key>
<string>Name:</string>
<key>Description</key>
<string>The name of the Model, View and ViewModel to create</string>
<key>Type</key>
<string>text</string>
<key>Default</key>
<string>MyModel</string>
</dict>
</array>
</dict>
</plist>
cf) storyboard도 자동으로 생성하고 싶은 경우, .storyboard 파일명 사용
- .storyboard 파일을 열어서 class와 storyboardID에도 이름 입력
- 테스트
Template 관리 방법
* 아이디어: 구현한 jake.xctemplate 폴더만 git에 올려놓고, 다운받아서 terminal을 통해 아래 경로로 저장하도록 shell script를 프로젝트 폴더에 구현하여 사용
cd ~/Library/Developer/Xcode/Templates/File\ Templates/jake.xctemplate
- jake.xctemplate 폴더를 프로젝트에 copy
cp -r ~/Library/Developer/Xcode/Templates/File\ Templates/jake.xctemplate ~/desktop/work
- 프로젝트 폴더 안에 Templates 폴더 안으로 복사&붙여넣기 하는 shell script 추가
cp -r jake.xctemplate ~/Library/Developer/Xcode/Templates/File\ Templates/
- 모든 사용자가 실행할 수 있도록 권한 변경
chmod 777 set_template.sh
- 실행
./set_template.sh
* 전체 소스 코드: https://github.com/JK0369/Work
cf) ReactorKit template 예시: https://ios-development.tistory.com/784
* 참고
- http://jeanetienne.net/2017/09/10/advanced-xcode-template.html