16
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Swift Package Managerで、Private Repositoryを利用する

Last updated at Posted at 2022-09-15

Swift Package Manager(以下、SPM)の登場から数年が経ち、実務でも導入事例が増えてきました。
しかし、有名なFrameworkであっても、依然としてSPM非対応のものは少なくありません。

本記事では、SPM非対応FrameworkをXCFramework化してSPMで管理する方法、およびPrivate RepositoryのRelease Assetを利用する方法について整理します。


SPMとXCFramework

SPMは、binaryTarget を使って XCFramework形式のバイナリ を依存関係として登録できます。
これにより、SPM非対応のFrameworkでもXCFramework形式にビルドして登録すれば、SPMで擬似的に管理可能です。

XCFrameworkの参照方法は以下の2通りです。

  1. ローカル参照
  2. サーバーからバイナリをホスティング

サーバー配布の場合は、XCFrameworkを含むZIPファイルを作成し、公開します。
Package.swift の例は以下の通りです。

// Package.swift
import PackageDescription

let package = Package(
    name: "AppPackage",
    products: [
        .library(name: "HogeUtil", targets: ["HogeUtil"]),
    ],
    targets: [
        .binaryTarget(
            name: "HogeUtil",
            url: "https://example.com/HogeUtil.xcframework.zip",
            checksum: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
        ),
    ]
)

非公開Frameworkの場合は、Git LFS や AWS S3 など、限定アクセス可能な場所にバイナリを置く必要があります。


Private RepositoryのRelease Assetは以前使えなかった

GitHubで管理している非公開FrameworkをRelease Assetとして配布できれば、
自前でホスティングする必要もなく便利です。

しかし、以前はGitHub認証周りの問題で Private RepositoryのRelease AssetをSPMから直接参照できませんでした
実際、以下フォーラムにも同様の報告があります。


先行事例:リポジトリ同梱方式

リポジトリ本体にXCFrameworkを同梱して配布する方法です。
ただし、GitHubは100MB以上のファイルを置けないため、バイナリが小さい場合に限られます。


なぜRelease Assetを使えなかったのか

原因は大きく2つありました。

1. ダウンロードURLが直接利用できない

Release AssetのURLは直接ZIPを返さず、302リダイレクトを返します。
SPMのURLSessionはリダイレクト先を取得せず、.zip拡張子必須という制約もあるため利用できませんでした。

2. Accept: application/octet-stream ヘッダーがなかった

GitHub API仕様に沿ったヘッダーが付与されておらず、ダウンロードに失敗していました。
現在は以下PRにより解決しています。


Xcode 13.3以降で解決済み

これらの問題はXcode 13.3以降で解消され、Private RepositoryのRelease Assetも利用可能になりました。


Private RepositoryのRelease Assetを使う手順

SPM対応Frameworkを使うよりは手間がかかりますが、ビルド高速化などのメリットもあります。

前提条件

  • FrameworkがGitHubリポジトリで管理されている
  • Tag / Releaseが発行されている
  • Release AssetにXCFrameworkのZIPがアップされている

1. 最新Releaseの取得

GitHub APIで最新Release情報を取得します。

curl   -H "Accept: application/vnd.github+json"   -H "Authorization: Bearer <YOUR-TOKEN>"   https://api.github.com/repos/OWNER/REPO/releases/latest

レスポンスのassets.urlを控えておきます。


2. Checksumの取得

ZIPをダウンロードし、Checksumを計算します。

swift package compute-checksum HogeUtil.xcframework.zip

3. Package.swiftにbinaryTargetを追加

import PackageDescription

let package = Package(
    name: "AppPackage",
    products: [
        .library(name: "HogeUtil", targets: ["HogeUtil"]),
    ],
    targets: [
        .binaryTarget(
            name: "HogeUtil",
            url: "https://api.github.com/repos/OWNER/REPO/releases/assets/ASSET_ID.zip", // .zip必須
            checksum: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
        ),
    ]
)

4. .netrc の作成

SPMは .netrc での認証設定に対応しています。
アクセストークンを作成し、以下のように記載します。

touch ~/.netrc
machine api.github.com login <GITHUB-USERNAME> password <ACCESS-TOKEN>

今後の検証課題

  • CIでの.netrc設定方法
  • ビルド速度への影響

まとめ

  • Xcode 13.3以降なら、Private RepositoryのRelease AssetをSPMのbinaryTargetとして利用可能
  • .netrcによる認証設定でダウンロードできる
  • 公開不要で、安全に非公開FrameworkをSPM管理できる

SPMの活用範囲が広がるため、今後CocoaPodsやCarthageからの移行手段の一つとして有力です。


参考リンク

16
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?