관리 메뉴

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

[iOS - swift] 5. Tuist 사용 방법 - static framework, dynamic framework 생성 방법, 의존성 관리 방법 본문

iOS 응용 (swift)

[iOS - swift] 5. Tuist 사용 방법 - static framework, dynamic framework 생성 방법, 의존성 관리 방법

jake-kim 2023. 3. 16. 01:50

* 목차

프로젝트 준비

  • 이전 포스팅글에서 알아본대로 아래처럼 세팅
.
└── Tuist
    └── Templates
        └── app
            ├── AppDelegate.stencil
            ├── LaunchScreen.stencil
            ├── Project.stencil
            ├── ViewController.stencil
            ├── Workspace.stencil
            └── app.swift
  • tuist scaffold app --name MyApp 실행
.
├── Tuist
│   └── Templates
│       └── app
│           ├── AppDelegate.stencil
│           ├── LaunchScreen.stencil
│           ├── Project.stencil
│           ├── ViewController.stencil
│           ├── Workspace.stencil
│           └── app.swift
├── Workspace.swift
└── Workspaces
    └── MyApp
        ├── Project.swift
        └── Sources
            ├── AppDelegate.swift
            ├── LaunchScreen.storyboard
            └── ViewController.swift
  • tuist generate 실행

Dynamic Framework, Static Framework 추가

* static framework, dynamic framework 개념은 이전 포스팅 글 참고

  • Framework를 추가하려면 Project.stencil안에 있는 내용을 변경하여 사용
    • product 부분에 .framework 입력 (dynamic framework)
    • 만약, static framework를 만들고 싶다면 static framework 입력
  • dynamic framework 생성
    • 아래처럼 Project.stencil 파일을 변경
    • tuist scaffold app --name MyApp2 실행
    • tuist generate 실행
import ProjectDescription

let project = Project(
    name: "{{ name }}",
    targets: [
        Target(
            name: "{{ name }}",
            platform: .iOS,
            product: .framework, // <-
            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") #}
            ]
        )
    ]
)
  • static framework 생성ㅇㅇ
    • 아래처럼 Project.stencil 파일을 변경
    • tuist scaffold app --name MyApp3 실행
    • tuist generate 실행
import ProjectDescription

let project = Project(
    name: "{{ name }}",
    targets: [
        Target(
            name: "{{ name }}",
            platform: .iOS,
            product: .staticFramework, // <-
            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") #}
            ]
        )
    ]
)

만들어진 .app(MyApp), .dynamicFramework(MyApp2), .staticFramework(MyApp3)

dependency 설정

  • Xcode에서 설정하려면 아래처럼 설정하면 되지만 tuist로 프로젝트를 만들면 dependency가 풀려 있을 것이므로 tuist에서 dependency 지정이 필요

  • tuist에서 dependency 지정
    • MyApp/Project.swift파일의 dependencies부분을 .project로 추가하여 디펜던시 추가
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: [ // <-
                .project(target: "MyApp2", path: "../MyApp2"),
                .project(target: "MyApp3", path: "../MyApp3")
            ]
        )
    ]
)
  • tuist generate하면 자동으로 주입되어있음
    • MyApp2는 dynamic framework라서 자동으로 Embed로 설정
    • MyApp3는 static framework라서 자동으로 Do Not Embed로 설정 

(* static framework, dynamic framework 개념은 이전 포스팅 글 참고)

  • MyApp에서 두 프레임워크 접근도 가능

왜 UIKit은 dynamic framework인가?

  • 여러곳에서 사용될 수 있으므로 dynamic framework를 사용
    • 코드 중복 방지 (static같은 경우 의존성을 잘못 설정하면 코드 복사가 여러번 이루어져서 코드 중복의 위험이 존재)
    • 앱의 크기 감소
    • 빠른 빌드에 유리(static framework는 앱의 실행파일에 포함되므로 매번 빌드가 필요하지만 dynamic framework는 별도로 컴파일하여 Bundle에 올려서 런타임에 link하여 사용하므로 매번 빌드가 필요x)

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

* 참고

https://tuist.io/

Comments