안녕하세요 🙇🏻♂️
프로젝트를 진행하다보면 git merge를 하는 과정에서 .pbxproj파일 conflict로 고생하는 경우가 종종있는데
그것을 해결하고자 Tuist를 적용해보자해서 쓰는 포스팅임다
포스팅은 편의상 편의 말투로 진행함다 😎
Tuist란?
Tuist는 iOS 및 macOS 애플리케이션의 프로젝트와 작업 공간을 효율적으로 관리하고 생성할 수 있게 도와주는 오픈 소스 도구입니다. Tuist는 Xcode 프로젝트의 구성과 설정을 코드로 정의하고 관리할 수 있게 해줍니다. 이를 통해 복잡한 프로젝트 설정을 자동화하고 일관성을 유지할 수 있습니다.
Tuist는 초기 설정이 복잡하고 시간이 많이 들어가지만 세팅 이후에는 모듈 생성과 모듈간의 의존성 정의가 매우 간편해집니다
이게 무슨말이냐 라고 생각 되는분들이 많을탠데
예를들어 App의 bundle ID, 앱 이름 등..을 바꾸려면 xcode내의 프로젝트에서 설정을 바꾸어줘야 하는데
그 작업을 Tuist가 대신한다는거임 😎
Tuist를 적용했을시 기대되는 효과
1. 프로젝트 설정의 코드화
• Tuist는 Project.swift와 Config.swift, Package.swift 파일을 사용하여 프로젝트와 작업 공간의 설정을 코드로 정의할 수 있습니다. 이로 인해 프로젝트 설정의 버전 관리가 용이해집니다.
2. 종속성 관리
• Tuist는 Swift Package Manager (SPM) 및 Cocoapods와 같은 외부 종속성을 통합할 수 있는 기능을 제공합니다. 이를 통해 종속성의 설치 및 업데이트가 자동화됩니다.
3. 일관성 유지
• Tuist를 사용하면 팀원 간의 프로젝트 설정이 일관되게 유지됩니다. 모든 팀원이 동일한 설정을 사용하므로 환경 차이로 인한 문제를 줄일 수 있습니다.
4. 자동화된 프로젝트 생성
• Tuist는 명령어를 통해 Xcode 프로젝트를 자동으로 생성하고 설정합니다. 이를 통해 새로운 프로젝트를 빠르게 시작하고 설정할 수 있습니다.
5. 확장성과 재사용성
• Tuist는 여러 프로젝트에서 재사용할 수 있는 모듈화된 설정을 지원합니다. 공통 설정을 모듈화하여 여러 프로젝트에서 재사용할 수 있습니다.
6. 설정의 가독성 향상
• Tuist의 설정은 코드로 작성되므로, 텍스트 기반의 설정 파일보다 읽기 쉽고 유지보수가 용이합니다.
Tuist를 사용하여 모듈화하기
Tuist 설치
curl -LS https://install.tuist.io | bash
프로젝트를 생성할 디렉토리로 이동 후 Tuist로 iOS 프로젝트 생성
tuist init --platform ios // UIKit
tuist init --platform ios --template swiftui // SwiftUI
Project.swift를 수정하는 명령어 Tuist Edit을 실행
tuist edit
여기까지 수행하면 Xcode에서 Project.swift파일이 열리게 됨!
Project.swift
해당 파일은 아래와 같은 이니셜라지어를 가지고 있음.
public init(
name: String,
organizationName: String? = nil,
options: ProjectDescription.Project.Options = .options(),
packages: [ProjectDescription.Package] = [],
settings: ProjectDescription.Settings? = nil,
targets: [ProjectDescription.Target] = [],
schemes: [ProjectDescription.Scheme] = [],
fileHeaderTemplate: ProjectDescription.FileHeaderTemplate? = nil,
additionalFiles: [ProjectDescription.FileElement] = [],
resourceSynthesizers: [ProjectDescription.ResourceSynthesizer] = .default
)
- name
- 프로젝트 이름 - organizationName
- organization의 이름 - options
- Tuist가 xcodeproj 파일을 만들 때의 옵션을 설정 - packages
- SPM의 package를 의미 - settings
- 프로젝트 파일에 있는 build settings의 정보들을 설정
- Dictionary로 값 부여 - targets
- 프로젝트의 타겟을 의미
Target의 이니셜라이저
public init(
name: String, // 타겟의 이름
platform: ProjectDescription.Platform, // iOS, macOS, tvOS, watchOS 같은 플랫폼을 의미
product: ProjectDescription.Product, // app, appClips, staticFramework, framework, unitTest 등을 의미
productName: String? = nil, // 만들어진 product의 이름
bundleId: String, // 프로젝트 파일을 열었을 때 보이는 Bundle Identifier
deploymentTarget: ProjectDescription.DeploymentTarget? = nil, // 배포 타겟을 설정
infoPlist: ProjectDescription.InfoPlist? = .default, // info.plist를 정의
sources: ProjectDescription.SourceFilesList? = nil, // 소스코드의 경로를 입력
resources: ProjectDescription.ResourceFileElements? = nil, // 앞서서 resourceSynthesizers에서 Tuist가 Resources/ 의 리소스들을 자동으로 코드화한다고 했는데, 그때 이 리소스들이 어디에 있는지에 대한 경로를 의미
copyFiles: [ProjectDescription.CopyFilesAction]? = nil, // 타겟에 대한 Build Phase 파일 복사 작업
headers: ProjectDescription.Headers? = nil, // 타겟에 대한 headers
entitlements: ProjectDescription.Path? = nil, // 타겟에 대한 entitlements의 경로를 입력
scripts: [ProjectDescription.TargetScript] = [], // 타겟에 대한 build Phase 스크립트 작업
dependencies: [ProjectDescription.TargetDependency] = [], // 타겟의 의존성에 대한 것을 의미한다.
settings: ProjectDescription.Settings? = nil, // 타겟의 세팅을 정의한다.
coreDataModels: [ProjectDescription.CoreDataModel] = [], // CoreData의 모델들의 경로랑 버전을 정의한다.
environment: [String : String] = [:], // scheme에서 Edit Scheme… 버튼을 누르면 나오는 창에서 Environment Variables를 설정할 수 있는데 이때 environment를 설정하면 자동으로 생성
launchArguments: [ProjectDescription.LaunchArgument] = [], // scheme에서 Edit Scheme… 버튼을 누르면 나오는 창에서 Arguments Passed On Launch를 설정할 수 있는데 이때 launchArguments 설정하면 자동으로 생성
additionalFiles: [ProjectDescription.FileElement] = [] // 프로젝트를 생성할 때 자동으로 생겨나지 않는 파일을 등록
)
- schemes
- 프로젝트의 scheme을 의미 - fileHeaderTemplate
내장 Xcode Template에 Custom으로 파일 헤더를 만들 수 있다.
import ProjectDescription
let project = Project(
name: "tuist-project",
organizationName: "organizationName",
targets: [
.target(
name: "tuist-project",
destinations: .iOS,
product: .app,
bundleId: "io.tuist.tuist-project",
infoPlist: .extendingDefault(
with: [
"UILaunchScreen": [
"UIColorName": "",
"UIImageName": "",
],
]
),
sources: ["tuist-project/Sources/**"],
resources: ["tuist-project/Resources/**"],
dependencies: []
),
.target(
name: "tuist-projectTests",
destinations: .iOS,
product: .unitTests,
bundleId: "io.tuist.tuist-projectTests",
infoPlist: .default,
sources: ["tuist-project/Tests/**"],
resources: [],
dependencies: [.target(name: "tuist-project")]
)
],
fileHeaderTemplate: "Copyright © 2024 ukseung. All rights reserved." // Key: Value 추가
)
fileHeaderTemplate에 값을넣고
터미널에서 tuist generate하게 된다면 프로젝트가 생성이되는데 이제 새로운 파일을 만들때마다
맨위에 Copyright © 2024 ukseung. All rights reserved. 주석이 달림!
만약 "" 라면
//
import foundation
만약 default값인 nil이라면
//
// File.swift
// tuist-project
//
// created by ukseung.dev on 2024/08/13
// copyright © 2024 ukseung. All rights reserved.
//
import foundation
라이브러리 의존성 주입
tuist edit
⬇️
⬇️
tuist build // Tuist 프로젝트의 빌드
tuist generate // Project.swift 파일을 기반으로 Xcode 프로젝트를 생성합니다.
결론
협업시 문제가 되던 .pbxproj파일 conflict 이제 안녕
잘못 건들였다가 build도 안되는 불상사를 볼 수 있는데 tuist를 사용하면
프로젝트 설정을 코드화 하기 때문에 형상 관리가 더욱 수월 할 듯.
ref.
https://leeari95.tistory.com/74
'iOS > Swift' 카테고리의 다른 글
[Swift] Realm 기본 개념 및 간단 예제 (3) | 2024.09.06 |
---|---|
[iOS] Core Data 기본 개념 및 간단 예제 (2) | 2024.08.20 |
[Swift] Framework,SDK 생성 및 import 하는 방법 (1) | 2024.08.06 |
[Swift] Storyboard없이 CodeBaseUI 코드 구현 (0) | 2024.05.31 |
[Swift] 앱 빌드 오류, failed: Operation not permitted (1) (2) | 2023.11.29 |