728x90
반응형

안녕하세요 🙇🏻‍♂️

프로젝트를 진행하다보면 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

⬇️

package와, target의 dependencies의 값 추가

⬇️

tuist build // Tuist 프로젝트의 빌드
tuist generate // Project.swift 파일을 기반으로 Xcode 프로젝트를 생성합니다.

 

Xcode가 자동으로 열리며 프로젝트 네비게이터에 Package Dependencies, ReactorKit이 추가된 것을 확인

 

결론

협업시 문제가 되던 .pbxproj파일 conflict 이제 안녕

잘못 건들였다가 build도 안되는 불상사를 볼 수 있는데 tuist를 사용하면 

프로젝트 설정을 코드화 하기 때문에 형상 관리가 더욱 수월 할 듯.

 

ref. 

https://leeari95.tistory.com/74

https://tuist.io

 

 

728x90
반응형
욱승