"TEST SUCCEEDED. 테스트 2개 실행, 원래 있던 그 두 개. 새 테스트 파일은 어디서도 컴파일되지 않았어."
iOS엔 Xcode 프로젝트가 필요한데, 아무도 손으로 안 고치는 이유
SwiftPM 패키지로는 iOS 앱을 표현 못 해. 에셋 카탈로그와 앱 아이콘, 앱에 내장하는 공유 확장과 워치 앱, 엔타이틀먼트, 명시적인 Info.plist, 프로비저닝, 테스트 호스트 같은 것들 말이야. 이런 건 .xcodeproj에 들어가는데, 그 안의 project.pbxproj는 사람이 손으로 병합하면 안 되는 파일이야. 이 딜레마를 푸는 게 XcodeGen이야. 사람이 읽을 수 있는 project.yml을 쓰고 xcodegen generate를 돌리면, 거기서 Xcode 프로젝트가 만들어져. 이 가족의 iOS랑 워치 앱은 전부 이렇게 해. YAML이 원본이고, 프로젝트는 결과물이야.
project.yml에 들어가는 것
- 프로젝트 전체 설정은 절대 어긋나면 안 돼.
DEVELOPMENT_TEAM,CODE_SIGN_STYLE: Automatic,SWIFT_VERSION, 그리고 프로젝트 수준의MARKETING_VERSION과CURRENT_PROJECT_VERSION이 여기 들어가. 그래야 앱과 확장이 늘 같은 버전 쌍을 달아. App Store Connect는 번호가 호스트랑 다른 확장을 거부하거든. packages에는 공유 Swift 패키지를 path로 적어.targets에는 앱(type: application), 확장(app-extension), 워치 앱, 테스트 번들이 들어가. 타깃마다 소스, 의존성,info속성,entitlements속성, 스킴이 붙어.
다음 생성 때 사라지는 클릭 두 개
Xcode UI에서 바꾸는 건 전부 생성된 프로젝트를 바꾸는 거고, 다음 xcodegen generate가 그걸 갈아엎어. Signing & Capabilities에서 고른 팀도 다음 생성 전까지만 유효해. 그래서 팀 ID를 project.yml에 적어 두는 거야. 가족이 빌드 번호를 올릴 때도 pbxproj가 아니라 project.yml을 고쳐.
스위트가 한 번도 안 돌린 파일
XcodeGen은 실행되는 순간의 파일 목록을 고정해 둬. 그 뒤에 추가한 .swift 파일은 프로젝트에 아예 없어. 앱 소스라면 "타입을 찾을 수 없음" 에러로 드러나지만, 테스트 파일이면 아무 소리도 안 나. xcodebuild test는 새 테스트를 한 번도 돌리지 않은 채, 프로젝트가 원래 알던 테스트만 돌리고 ** TEST SUCCEEDED **를 찍어. 가족은 이걸 두 겹으로 막았어. 첫째, 테스트 스크립트가 xcodebuild test 전에 xcodegen generate를 돌려. 둘째, 소스와 테스트 폴더의 Swift 파일이 전부 생성된 프로젝트에 들어 있는지 검사해. 그래서 프로젝트가 낡았으면 엉터리 통과를 찍는 대신 요란하게 실패해. (생성된 프로젝트를 커밋할지는 가족 레포마다 달라. 어느 쪽이든 결과를 믿기 전에 다시 생성해.)