Skip to content

Package를 이용한 모듈화

Jerry_hoyoung edited this page Jan 2, 2023 · 1 revision

🏠 동네 한입팀이 Package를 이용해 모듈화했던 과정을 담아보고자 작성합니다.

SPM을 사용한 동네한입 App

동네 한입 App은 SPM을 이용해 의존성을 관리하기로 결정하였습니다.

SPM이란 Swift Package Manager로 코드 배포를 관리하는 도구로 모듈화, 의존성을 관리하는 하도록 만들어졌습니다.

의존성 관리도구로 SPM을 선택한 이유

  • Cocoa pods과 비교하여 1st party 종속 관리 도구로써 유지 측면에서 유리하다고 판단
  • Cocoa pods을 사용하게 되면 다른 framework를 추가할 시에 PodFile에 수동으로 추가해야하는 불편함이 있음

모듈화

SPM을 선택한 저희 팀은 모듈화도 진행하는 계획을 세웠습니다

모듈화를 진행했던 이유는 크게 두가지 였습니다

  • 빌드 속도 개선

    코드 파일들이 모듈화되어 있으면 빌드 시 변경된 부분만 빌드되기 때문에 빌드 속도가 향상

  • 코드 결합도 낮춤

    코드 파일들 간의 결합도가 줄어들어 개발 구조를 관리하기 용이하고 협업 측면에서도 편리 (Project파일 충돌..)

따라서 저희 동네한입 App에서는 총 네가지 모듈로 구성할 계획을 세웠습니다


Core → 기본이 되는 BaseController들, Logging, FoundationKit extensions 등으로 구성

UI → 공통 UI Components (Button, Label), UIKit extensions, resource 등 구성

NetWork → 네트워크 관련 코드를 담고있는 파일로 구성

App → 동네 한입 App


Package, Framework 어떤 것으로 모듈화를 진행할까?

framework는 파일,리소스를 포함한 캡슐화된 계층 디렉터리입니다. 그리고 package는 소스파일과 같이 Package.swift인 manifest 파일로 구성되어 있습니다.

Package는 swift 소스 파일로 배포되기 때문에 바이너리 호환성을 유지하지 않아도 됩니다

사실 두개의 차이는 크게 없는 것같아 보여서..

xcode workspace를 이용하지 않고 (실수로 프로젝트 파일 누르면 완전 짜증..)

익숙하지 않은 package를 도전해봅니다 👊


Local Package를 추가하자

  1. File → add packages 메뉴 → 내 Add Local 버튼을 누르면 local packge를 생성할 수 있다

    스크린샷 2023-01-03 오전 2 28 27

    스크린샷 2023-01-03 오전 2 30 53

  2. 내 프로젝트에 패키지 파일을 드래그하여 import 시킵니다

    이전 패키지 xcode는 꺼야합니다

  3. 프로젝트 내 Frameworks, libraries, and Enbedded Content에 각 package를 추가

    스크린샷 2023-01-03 오전 2 31 51

  4. 각 package 파일의 Package.swift 파일을 통해 의존성 관리

    let package = Package(
        name: "FindTownCore",
        platforms: [
            .iOS(.v15)
        ],
        products: [
            // Products define the executables and libraries a package produces, and make them visible to other packages.
            .library(
                name: "FindTownCore",
                targets: ["FindTownCore"]),
        ],
        dependencies: [
            // Dependencies declare other packages that this package depends on.
            // .package(url: /* package url */, from: "1.0.0"),
            .package(url: "https://github.com/ReactiveX/RxSwift", branch: "main"),
            .package(path: "../FindTownUI")
        ],
        targets: [
            // Targets are the basic building blocks of a package. A target can define a module or a test suite.
            // Targets can depend on other targets in this package, and on products in packages this package depends on.
            .target(
                name: "FindTownCore",
                dependencies: ["RxSwift","FindTownUI"]),
            .testTarget(
                name: "FindTownCoreTests",
                dependencies: ["FindTownCore"]),
        ]
    )

    패키지 별로 의존성을 넣는 방식이 여러가지인데

    • SPM에 오픈 소스로 배포되어 있는 경우에는 github url로 dependencies를 추가하고 targetdp 넣어주면 됩니다
    • 내부 프로젝트에 있는 local package를 의존하고 싶은 경우 path를 이용하여 추가합니다

너무 간단하다~!


이번에 package로 모듈화를 작업해본 경험으로 다음 프로젝트때는 민소네님처럼 framework, package를 같이 사용하여 모듈화해보는 경험도 해보고 싶습니다 🙂

감사합니다


[참고]

Apple Developer Documentation

[Swift 5.2][SwiftPM] Swift Package Manager를 이용하여 패키지를 통합 관리하기 - Proxy Module

Libraries, frameworks, swift packages... What's the difference?