버그 잡이

Tuist 삽질기 (1) - tuist란 무엇이고 어떻게 쓰는건가? 본문

IOS

Tuist 삽질기 (1) - tuist란 무엇이고 어떻게 쓰는건가?

버그잡이 2023. 4. 30. 15:00

Tuist

 

Tuist는 Xcode 프로젝트를 관리할 수 있는 툴입니다.

기존에 Xcode에서 target, SPM, info, buid-setting 을 관리하던 것을 tuist라는 툴을 활용해서 할 수 있는 것입니다.

 

Tuist의 장점

1. 모듈화를 할 수 있다.

- 모듈화를 하면 모듈별 의존성이 낮아지고 재활용성이 높아집니다.

-> 유지보수 하기 좋은 코드, 구조가 됨

-> 빌드 속도 향상

 

2. pbxproj 충돌을 줄일 수 있다.

- 협업하다보면 많은 변경 사항을 merge 하는 과정에서 .pbxproj파일 충돌로 고생하는 경우가 종종있는데 tuist를 쓰면 이를 줄일 수 있다고 합니다.

 

 

 

Tuist 로 프로젝트 생성해보기

 

1. Tuist 설치

curl -Ls https://install.tuist.io | bash

 

 

2. Tuist로 iOS 프로젝트 설정

터미널로 프로젝트를 생성할 경로에 진입하여 아래 명령어 실행

* 폴더가 빈 폴더여야 합니다.

tuist init --platform ios   // UIKit
tuist init --platform ios --template swiftui   // SwiftUI

 

 

3. tuist edit

터미널에서 tuist edit 명령어를 실행하면 아래와 같은 구조의 프로젝트가 실행됩니다.

여기서 보이는 Project.swift 파일을 활용해서 프로젝트 관련 설정을 할 수 있습니다.

(Project.swift 파일은 tuist에서 .xcodeproj를 어떻게 만들지 정의하는 파일입니다.)

 

 

4. Project 파일 설정

Project 파일에서는 다양한 설정이 가능한데요. 

기본 설정한 옵션들을 보면서 어떻게 구성되는지 감을 익혀보겠습니다.

import ProjectDescription

private let bundleId: String = "com.sangjin.tuisttest"
private let version: String = "0.0.1"
private let bundleVersion: String = "1"
private let iOSTargetVersion: String = "16.0"

private let basePath: String = "Targets/TuistTest2"
private let appName: String = "TuistTest2"

let project = Project(name: appName,
                      targets: [
                        Target(
                            name: "TuistTest",
                            platform: .iOS,
                            product: .app,
                            bundleId: bundleId,
                            deploymentTarget: .iOS(targetVersion: iOSTargetVersion, devices: .iphone),
                            infoPlist: makeInfoPlist(),
                            sources: ["\(basePath)/Sources/**"],
                            resources: ["\(basePath)/Resources/**"],
                            settings: baseSettings()
                        )
                      ],
                      additionalFiles: [
                        "README.md"
                      ])

private func makeInfoPlist(merging other: [String: InfoPlist.Value] = [:]) -> InfoPlist {
    var extendedPlist: [String: InfoPlist.Value] = [
        "UIApplicationSceneManifest": ["UIAppliactionSupportsMultipleScenes": true],
        "UILaunchScreen": [],
        "UISupportedInterfaceOrientations":
            [
                "UIInterfaceOrientationPortrait",
            ],
        "CFBundleShortVersionString": "\(version)",
        "CFBundleVersion": "\(bundleVersion)",
        "CFBundleDisplayName": "\(appName)",
    ]
    
    other.forEach { (key: String, value: InfoPlist.Value) in
        extendedPlist[key] = value
    }
    
    return InfoPlist.extendingDefault(with: extendedPlist)
}

private func baseSettings() -> Settings {
    var settings = SettingsDictionary()
    
    return Settings.settings(base: settings,
                             configurations: [],
                             defaultSettings: .recommended)
}

* target

- 프로젝트의 타켓

- 최소 1개 이상의 target을 가지고 있어야 한다. 또 다른 타겟 추가 가능 ex) "TuistTest-dev"

 

* infoPlist

- 기존에 info.plist 에서 해줬던 설정을 여기서 진행

 

* source

- 소스코드의 경로

 

* resource

- 리소스 파일의 경로

 

* additionalFiles

- Tuist에서 프로젝트를 만들때 자동으로 Xcode에 연결해주지 않는 파일들을 추가

 

 

 

모듈 추가해보기: CustomUI 

 

모듈화를 위해서 쓰는 tuist라고 했으니 CustomUI라는 모듈을 하나 추가해보겠습니다.

 

1. Xcode에서 'Command + Shift + n'으로 Swift Package 프로젝트를 생성합니다.

1) 아래와 같이 화면이 나올텐데 Swift Package를 선택합니다.

2) 프로젝트 안에 "SwiftPackage"라는 폴더를 만들고 그 안에 CustomUI 패키지를 생성했습니다.

(물론 폴더를 따로 만들지 않고 생성해도 됩니다. 프로젝트 안에만 위치하면 됩니다.)

 

 

  2. 위에서 설정했던 Project 파일로 돌아가서 dependency를 추가해줍니다.

"packages"와 "dependencies" 를 추가해줬습니다.

private let swiftPackagePath: String = "SwiftPackages"

let project = Project(name: appName,
                      packages: [
                        .package(path: "\(swiftPackagePath)/CustomUI"),
                      ],
                      targets: [
                        Target(
                            name: "iOS",
                            platform: .iOS,
                            product: .app,
                            bundleId: bundleId,
                            deploymentTarget: .iOS(targetVersion: iOSTargetVersion, devices: .iphone),
                            infoPlist: makeInfoPlist(),
                            sources: ["\(basePath)/Sources/**"],
                            resources: ["\(basePath)/Resources/**"],
                            dependencies: [
                                .package(product: "CustomUI"),
                            ],
                            settings: baseSettings()
                        )
                      ],
                      additionalFiles: [
                        "README.md"
                      ])

 

이 결과 CustomUI 패키지에 접근이 가능하고 

이후 클래스 내부에서 CustomUI를 import하면 CustomUI 패키지 안에 있는 file에 접근할 수 있습니다.

(물론 다른 모듈에서 접근하는 것이기 때문에 CustomUI에 있는 객체들은 pulbic 또는 open으로 선언되어 있어야 합니다.)

 

 

 

* 참고 자료

https://leeari95.tistory.com/74

https://www.youtube.com/watch?v=1inP-Y118p8 

 

 

 

 

반응형
Comments