본문 바로가기

프로그래밍/iOS,macOS

Framework SPM 배포

spm 으로 framework 를 배포하기 위해서는 swift 5.3 이상이 필요하고, xcframework 로 빌드되어야 한다.
아키텍처별로 framework 생성후에 xcframework 를 생성한다.

XCFramework 만들기 (tistory.com)

 

생성된 xcframework 를 git 저장소에 업로드
해당 저장소에 Package.swift 파일 생성한다.

// swift-tools-version:5.3
import PackageDescription

let package = Package(
    name: "MyLibrary",
    platforms: [
        .iOS(.v13),
    ],
    products: [
        .library(name: "MyLibrary", targets:["MyFramework"]),
    ],
    dependencies: [],
    targets: [
        .binaryTarget(name: "MyFramework", path: "MyFramework.xcframework")
    ]
)

Package.swift 파일은 '// swift-tools-version:5.3' 으로 시작되어야 하고, 현재 패키지 정보들을 구성한다.
다른 프로젝트에서 SPM으로 저장소를 추가할때 xcode에서는 package.swift 파일을 읽어 프로젝트에 포함시키게 된다.

binaryTarget 의 경우 별도 원격이나 url로 바이너리 위치를 지정하는 경우(zip 등으로 압축된 상태)  .binaryTarget(name:url:checksum:) 를 사용하고, 별도 checksum을 제공해야 한다.
로컬이나 path 지정방식인 경우에는 .binaryTarget(name:path) 로 checksum은 필요하지 않다.

swift package compute-checksum MyLibrary.xcframework.zip



binaryTarget은 다른 라이브러리를 사용하는 경우 dependencies 를 지원하지 않는다.
이 경우에는 별도의 패키징용 타겟을 생성해서 참조하는 라이브러리들을 구성해야 한다.

타겟 추가

// swift-tools-version:5.3
import PackageDescription

let package = Package(
    name: "MyLibrary",
    platforms: [
        .iOS(.v13),
    ],
    products: [
        .library(name: "MyLibrary", targets:["MyFrameworkBundle"]),
    ],
    dependencies: [
    
    ],
    targets: [
        .binaryTarget(name: "MyFramework", path: "MyFramework.xcframework")
        .target(name: "MyFrameworkBundle",
            dependencies: [ .target(name: "MyFramework")],
            path: "MyFrameworkBundle")
    ]
)

swift build를 해보면 path가 없다는 오류가 나올텐데 패키지용 타겟을 빌드하기 위한 소스파일을 추가해야 한다.
루트에 MyFrameworkBundle/MyFrameworkBundle.swift 을 추가한다. (내용은 비어 있어도 상관없음)

dependencies 에 사용하는 라이브러리 정보를 기술한다. 타겟에서 이름으로 사용하기 위해 name을 지정해 주어야 한다.

dependencies: [
   .package(name: "name", url: "git", from: "1.0.0"),
   .package(name: "name", url: "git", "1.0.0"..<"2.0.0"),
   .package(name: "name", url: "git", .exact("1.0.0")),
   .package(name: "name", url: "git", .branch("develop")),
   .package(name: "name", url: "git", .revision("aaaaaa")),
   .package(name: "name", path: "path")
]

 

패키지 타겟에 사용하는 라이브러리들의 이름을 dependencies 에 추가한다.

    targets: [
        .binaryTarget(name: "MyFramework", path: "MyFramework.xcframework")
        .target(name: "MyFrameworkBundle",
            dependencies: [ .target(name: "MyFramework"), "name", "name" ],
            path: "MyFrameworkBundle")
    ]

 

이제 이 라이브러리를 사용하는 프로젝트에서 spm 을 통해 다운로드 하면 dependencies에 등록된 패키지들도 같이 다운로드가 진행된다.