Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

teunteun2

[XCode] Hous-의 UIComponent SPM 모듈화 (1) - WWDC19 Creating Swift Packages 본문

iOS

[XCode] Hous-의 UIComponent SPM 모듈화 (1) - WWDC19 Creating Swift Packages

teunteun2 2023. 5. 20. 16:00

업데이트를 앞두고 있는 프로젝트 Hous-에 공통 UIComponent 들을 SPM으로 모듈화해보자 .. 하여

팀원들에게 공유할 겸 .. 공부할 겸 작성했습니다

 

https://developer.apple.com/videos/play/wwdc2019/410/

 

Creating Swift Packages - WWDC19 - Videos - Apple Developer

Whether you want to publish code to share with the community, or you just want a convenient way to organize the code in your apps, Swift...

developer.apple.com

https://developer.apple.com/videos/play/wwdc2018/411/

 

Getting to Know Swift Package Manager - WWDC18 - Videos - Apple Developer

The Swift Package Manager makes it possible to easily develop and distribute source code in the Swift ecosystem. Learn about its goals,...

developer.apple.com

 

 

1. Local Package를 만들고 적용하는 방법

 

1-1. File -> New -> Swift Package

위치 설정해주고

Add to , Group 도 해당 패키지를 넣을 프로젝트로 잘 설정해줍니다

 

 

 

1-2. Project -> Target -> Frameworks, Libraries, and Embedded Content

+ 버튼을 눌러서 방금 만들어둔 라이브러리를 추가해줍니다

 

 

 

1-3. import Library

import HousComponent

적용된 것을 새로고침 하려면 command + option + P

 

 

 

간단하죱 ? 하지만 패키지를 생성하고 적용할 때 가장 중요한 것은 Manifest 파일 설정입니다.

더 많은 옵션으로 패키지를 입맛에 따라 설정할 수 있고, 내가 만든 패키지에서 다른 라이브러리를 사용해야하는 경우엔 dependencies를 추가해야하기 때문인데요,

 

우선 방금 만들어둔 패키지를 로컬이 아닌 Git에 올리고 버전관리를 하는 방법을 알아보고 그 다음에 Manifest를 뜯어봅시당

 

 


 

 

2. 패키지를 Git에 올려 버전관리와 함께 사용하기

 

Option 키를 누른 채로 패키지를 프로젝트 밖으로 드래그 하면 패키지가 복사된다.

복사된 패키지는 패키지 파일을 더블클릭 하면 열림

열어보면 run destination이 Macs, tvOS,,모두 실행 가능한 것으로 보아

패키지는 플랫폼 환경에 구애받지 않는 것을 확인할 수 있다.

 

Test코드를 작성하고 Test를 통과한 것을 확인하면, 원격 저장소에 올려서 패키지를 Publish 할 수 있다

 

 

1. Source Control -> New Git Repositories

이렇게 하면 로컬 깃 레퍼지토리를 만들 수 있고, 커밋할 수 있다

 

 

2. 원격저장소에도 레퍼지토리를 만들기

SEM Navigator - Repositories로 가서 패키지의 context menu에서

New Remote ... 를 클릭한다. 그러면 현재 코드가 모두 원격 저장소에도 Publish 된다

 

 

3. tag 지정

SEM Navigator context menu 에서 tag를 지정하고 깃허브에 tag를 포함하여 Push 할 수도 있다

 

 

 

4. 프로젝트에 원격으로 올린 패키지 가져오기

프로젝트에서 로컬 패키지를 지우고 publish 된 패키지의 git 주소를 복사해서 SPM으로 넣으면 끝!

 

 


 

 

3. SPM manifest APIs

 

 

SPM 패키지는 Package Manifest 파일을 기본으로 가지고 있습니다. -> Package.swift

 

이 파일의 첫 줄은 항상 swift tools 버전으로 시작합니다.

해당 패키지를 실행하기 위해 필요한 Swift 컴파일러 최소 버전을 뜻합니다

// swift-tools-version: 5.7
// The swift-tools-version declares the minimum version of Swift required to build this package.

 

두번째 줄은 PackageDescription을 import 합니다.

XCode에서 제공하는 manifest 파일 생성에 필요한 API들을 가지고 있는 라이브러리 입니다

import PackageDescription

 

 

Package Initializer ✨

그 다음은 패키지 이니셜라이저 부분인데요,

let package = Package(
    name: "HousUIComponent",
    products: [
        
        .library(
            name: "HousUIComponent",
            targets: ["HousUIComponent"]),
    ],
    dependencies: [

    ],
    targets: [

        .target(
            name: "HousUIComponent",
            dependencies: []),
        .testTarget(
            name: "HousUIComponentTests",
            dependencies: ["HousUIComponent"]),
    ]
)

SwiftPM을 처음 만들어주면 위 코드와 같이 기본으로

패키지명과, 패키지명과 같은 라이브러리 product가 명시되어있고

Sources 폴더에 기본으로 있는 Target 폴더와 Tests 폴더에 기본으로 있는 TestTarget 폴더가 명시되어 있어요

 

SPM 기본 폴더 구조

 

 

 

기본 코드에서 알 수 있듯

패키지 이니셜라이저 부분에선 패키지의 이름을 설정해주고

Swift Package을 이루고 있는 Dependencies, Targets, Products를 설정해줍니다.

 

WWDC18 Getting to Know SwiftPM

 

 

 

 

 

Dependencies

패키지를 만들 때 외부 라이브러리가 필요할 수도 있어요. 이럴 때 Dependencies에 외부 라이브러리를 추가해줍니다.

 

url 다음에 오는 파라미터엔 다양한 방법으로 라이브러리 버전을 설정할 수 있습니다.

 

 

 

 

Targets

패키지 하나에 모듈 하나를 만들 수도 있고, 기능별로 다양한 모듈을 만들 수 있어요

Sources 파일에서 다양한 모듈을 만들 수 있습니다.

 

 Hous- UIComponent는 Button, Label, TextField, TextView 등 다양한 UI를 한번에 담을 패키지이기 때문에

기능별로 모듈을 나눌 수 있겠네요

 

Targets은 이러한 모듈을 정의합니다

 

 

 

 

 

아까 외부 라이브러리가 필요할 땐 dependencies에 명시해줬잖아요?

이 때 target마다 자신에게 필요한 외부 라이브러리를 각각 명시해줄 수 있습니다.

  dependencies: [
    .package(
      name: "ThirdPartyLibraryManager",
      path: "../ThirdPartyLibraryManager"
    ),
    .package(
      name: "AssetKit",
      path: "../AssetKit"
    )
  ],
  targets: [
    .target(
      name: "BottomSheetKit",
      dependencies: [
        .product(
          name: "ThirdPartyLibraryManager",
          package: "ThirdPartyLibraryManager"
        ),
        .product(
          name: "AssetKit",
          package: "AssetKit"
        )
      ]),
    .testTarget(
      name: "BottomSheetKitTests",
      dependencies: ["BottomSheetKit"]),
  ]

해당 코드는 Hous- 바텀시트 패키지 이니셜라이저의 dependencies & targets 부분인데요,

코드에서 알 수 있듯 ThirdPartyLibraryManagerAssetKitdependencies에서 명시해주고

BottomSheetKit targets 안에서 두 외부 라이브러리를 사용할 것이기 때문에 targets에서 다시 명시해준 것 보이시죠 ?

 

 

 

 

 

Products

Targets에 모듈들을 담아놓았다면 이젠 사용자가 해당 패키지 라이브러리를 쓸 수 있도록 해야합니다.

 

이 때 우리는 하나의 Target을 하나의 라이브러리로 만들수도,

여러개의 Target을 합쳐 하나의 라이브러리로 내보낼 수도 있습니다.

 

 

 

 

무슨말이냐면요,

HousUIComponent 패키지 내에

HousButton, HousLabel, HousTextField, HousTextView 총 4개의 Targets이 있다고 가정해봅시다.

products: [
    .library(
      name: "HousButton",
      targets: ["HousButton"]),
      
    .library(
      name: "HousLabel",
      targets: ["HousLabel"]),
      
    .library(
      name: "HousInputView",
      targets: ["HousTextField", "HousTextView"])
  ]

버튼과 레이블처럼 하나의 target을 하나의 라이브러리로 만들 수도 있고,

위 코드와 같이 TextField와 TextView target을 array로 묶어서 HousInputView라는 라이브러리로 내보낼 수도 있는거죠

 

아니면 아예 4개의 target을 한번에 묶어 HousUIComponent라는 이름의 라이브러리로 만들 수도 있고요!

 

 

 

 

 

 

더 많은 PackageDescriptionAPI가 있지만

가장 기본적인 것들만 정리하고 끝내보려고 합니다

더 많은 옵션은 여기서 ,,

 

https://docs.swift.org/package-manager/PackageDescription/

 

PackageDescription API — Swift Package Manager

 

docs.swift.org