관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 4. Tuist 사용 방법 - Dependencies.swift, 의존성 설정 방법, Project 단위로 나누는 방법 본문

iOS 응용 (swift)

[iOS - swift] 4. Tuist 사용 방법 - Dependencies.swift, 의존성 설정 방법, Project 단위로 나누는 방법

jake-kim 2023. 3. 15. 00:30

* 목차

Carthage, SPM 의존성 사용 방법

* starter project - github

  • Tuist에서 의존성 관리 방법
    • Tuist 하위 폴더 안에 Dependencies.swift파일이 있고, tuist fetch를 실행시켜 Dependencies 디렉토리에 프레임워크를 모아놓음
    • Project.swift 파일에서 Dependencies 의존성 설정을 할 수 있는데, 이 때 .external(name: "Alamofire")과 같이 추가하여 의존성 설정

현재 디렉토리 형태)

.
└── Tuist
    └── Templates
        └── app
            ├── AppDelegate.stencil
            ├── LaunchScreen.stencil
            ├── Project.stencil
            ├── ViewController.stencil
            └── app.swift
  • Dependencies.swift 파일을 Tuist 디렉토리 바로 하위에 추가
.
├── Dependencies.swift # <-
└── Templates
    └── app
        ├── AppDelegate.stencil
        ├── LaunchScreen.stencil
        ├── Project.stencil
        ├── ViewController.stencil
        └── app.swift
  • root 디렉토리 위체에서 tuist fetch 명령어를 입력하면 Dependencies 폴더가 생성
.
├── Dependencies.swift
└── Dependencies # <-
└── Templates
    └── app
        ├── AppDelegate.stencil
        ├── LaunchScreen.stencil
        ├── Project.stencil
        ├── ViewController.stencil
        └── app.swift
  • Dependencies 폴더 안에 아래처럼 lock 파일과 나머지 3rd party 폴더가 생성

(단, Alamofire가 2개가 있으면 중복되므로 의존성 설정 시 오류가 발생 -> Carthage 의존성 하나만 설정하도록 수정)

  • Dependencies.swift에 swiftPackageManager는 주석 처리
import ProjectDescription

let dependencies = Dependencies(
    carthage: [
        .github(path: "Alamofire/Alamofire", requirement: .exact("5.0.4")),
    ],
//    swiftPackageManager: [
//        .remote(url: "https://github.com/Alamofire/Alamofire", requirement: .upToNextMajor(from: "5.0.0")),
//    ],
    platforms: [.iOS]
)
  • tuist edit하여 Project.swift에서 해당 Alamofire를 의존하도록 수정
import ProjectDescription

let project = Project(
    name: "MyApp",
    targets: [
        Target(
            name: "MyApp",
            platform: .iOS,
            product: .app,
            bundleId: "com.jake.MyApp",
            infoPlist: .extendingDefault(with: [
                "CFBundleShortVersionString": "1.0",
                "CFBundleVersion": "1",
                "UILaunchStoryboardName": "LaunchScreen"
            ]),
            sources: ["Sources/**"], // Sources/**누락 시 .swift 파일 수동으로 add files해야 추가됨
            resources: ["Sources/**"], // Sources/**누락 시 LaunchScreen.storyboard 파일 수동으로 add files해야 추가됨
            dependencies: [
                .external(name: "Alamofire"),
            ]
        )
    ]
)
  • 다시 tuist fetch 후 tuist generate 수행 후 임포트 Alamofire 가능

  • Project.stencil 템플릿도 수정
import ProjectDescription

let project = Project(
    name: "{{ name }}",
    targets: [
        Target(
            name: "{{ name }}",
            platform: .iOS,
            product: .app,
            bundleId: "com.jake.{{ name }}",
            infoPlist: .extendingDefault(with: [
                "CFBundleShortVersionString": "1.0",
                "CFBundleVersion": "1",
                "UILaunchStoryboardName": "LaunchScreen"
            ]),
            sources: ["Sources/**"], // Sources/**누락 시 .swift 파일 수동으로 add files해야 추가됨
            resources: ["Sources/**"], // Sources/**누락 시 LaunchScreen.storyboard 파일 수동으로 add files해야 추가됨
            dependencies: [
                .external(name: "Alamofire")
            ]
        )
    ]
)

Project 단위로 관리 방법

* starter project: github

(위에서 의존성 설정한 Alamofire를 얻어오기위해 tuist fetch 먼저 수행)

  • 최종 목표 - Workspaces 디렉토리 하위에 새로 만들 모듈 (app, framework)들을 1열로 project단위로 나열하는 것

목표 - Workspaces 폴더 하위에 project단위로 구현

  • workspace로 관리하기 위해서는 Tuist에서 제공해주는 기능을 활용하면 쉽게 구현가능
    • Workspace.swift 파일이 루트 경로에 필요하여 Workspace.stencil파일도 템플릿안에 생성
.
└── Tuist
    ├── Dependencies.swift
    └── Templates
        └── app
            ├── AppDelegate.stencil
            ├── LaunchScreen.stencil
            ├── Project.stencil
            ├── ViewController.stencil
            ├── Workspace.stencil // <-
            └── app.swift

(Workspace.stencil 파일)

  • projects의 경로를 Workspaces/ 하위에 모든 파일로 설정하기위해 **를 두 개 붙여서 설정
import ProjectDescription

let workspace = Workspace(
    name: "MyApp",
    projects: [
        "Workspaces/**"
    ]
)
  • Workspaces하위로 Project들이 위치해야하므로, Project.swift 파일이 각 Workspaces/{{ name }} 위치로 이동하게끔 app.swift 수정필요

MyApp, MyApp2 하위에 각각의 Project.swift이 있도록 수정

(app.swift에서 sources들이 Workspaces 하위에 있도록 수정)

import ProjectDescription

let nameAttribute: Template.Attribute = .required("name")

let template = Template(
    description: "Custom template",
    attributes: [
        nameAttribute
    ],
    items: [
        .file(
            path: "Workspaces/\(nameAttribute)/Project.swift",
            templatePath: "Project.stencil"
        ),
        .file(
            path: "Workspace.swift",
            templatePath: "Workspace.stencil"
        ),
        .file(
            path: "Workspaces/\(nameAttribute)/Sources/AppDelegate.swift",
            templatePath: "AppDelegate.stencil"
        ),
        .file(
            path: "Workspaces/\(nameAttribute)/Sources/ViewController.swift",
            templatePath: "ViewController.stencil"
        ),
        .file(
            path: "Workspaces/\(nameAttribute)/Sources/LaunchScreen.storyboard",
            templatePath: "LaunchScreen.stencil"
        )
    ]
)
  • Project.stencil에서 Proejct.swift가 생성될 파일의 경로 (name: 부분)도 현재 디렉토리에 생성되도록 입력
    • *현재 디렉토리에 생성: 뒤에 생성될 MyApp, MyApp2 폴더와 같은 경로에 위치하도록 설정하는것
import ProjectDescription

let project = Project(
    name: "{{ name }}",
    targets: [
        Target(
            name: "{{ name }}",
            platform: .iOS,
            product: .app,
            bundleId: "com.jake.{{ name }}",
            infoPlist: .extendingDefault(with: [
                "CFBundleShortVersionString": "1.0",
                "CFBundleVersion": "1",
                "UILaunchStoryboardName": "LaunchScreen"
            ]),
            sources: ["Sources/**"], // Sources/**누락 시 .swift 파일 수동으로 add files해야 추가됨
            resources: ["Sources/**"], // Sources/**누락 시 LaunchScreen.storyboard 파일 수동으로 add files해야 추가됨
            dependencies: [
                .external(name: "Alamofire")
            ]
        )
    ]
)
  • 이제 차례대로 MyApp, MyApp2를 생성
tuist scaffold app --name MyApp 
tuist scaffold app --name MyApp2
  • generate
tuist generate

생성완료

  • Project 단위로 관리되므로 각각 scheme을 변경하여 실행할때도 편리

* 전체 코드: https://github.com/JK0369/ExTuist_4

* 참고

https://docs.tuist.io/guides/third-party-dependencies

 

Comments