この記事は ZOZO Advent Calendar 2023 Vol.8の16日目の記事です。
こんにちは。株式会社ZOZO 計測プラットフォーム開発本部 計測アプリ部 iOSブロックの@na9ainです。
本記事では、GitHubのプライベートリポジトリのRelease AssetsでXCFrameworkをホストして、Swift Package Manager・CocoaPodsで配布・利用する方法を紹介します。
はじめに
XCFrameworkをサーバー上でホストする必要性が生じる典型的な例は、XCFrameworkに含まれるファイルのサイズが100MBを超えるときです。
分かりやすさのために、このリポジトリを例として挙げます。
このリポジトリではSwift Package Manager・CocoaPodsでOpenCVのXCFrameworkを利用できるようにしています。
OpenCVのXCFrameworkはビルド時に、不要なモジュールを除外するなどの工夫をしない限り、バイナリのサイズが100MBを超えてしまい、GitHubのリポジトリにそのまま置くことができません。
このような問題の解決策の1つが、XCFrameworkをリポジトリに置くのではなく、Release Assetsでホストする方法です。
ここからは、このリポジトリを具体例として、配布側と利用側で必要な手順を紹介していきます。
配布編
XCFrameworkをzipにする
配布したいXCFrameworkをzipファイルにします。
zip -X -r -y opencv2.xcframework-4.8.1.zip opencv2.xcframework
XCFrameworkのzipをRelease Assetsにアップロードする
「Releases > Create a new release」から新しいリリースを作成します。
「↓ Attach binaries by dropping them here or selecting them.」からXCFrameworkのzipを選択して、アップロードします。
アップロードが完了したら、「Save draft」で作成したリリースをドラフトとして保存しておきます。
GitHub API URLを取得する
パブリックリポジトリであれば、https://github.com/thenagain/opencv-xcframework/releases/download/4.8.1/opencv2.xcframework-4.8.1.zip
という風に直接URLを指定してもよいのですが、プライベートリポジトリの場合、GitHub APIのURLを指定する必要があります。
Release AssetsにアップロードしたファイルのGitHub API URLはcurlコマンドで確認することができます。
curl -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ghp_XXXXXXXXXXXXXXXXXX"\
https://api.github.com/repos/thenagain/opencv-xcframework/releases
[
{
"url": "https://api.github.com/repos/thenagain/opencv-xcframework/releases/134107686",
.
.
.
"assets": [
{
"url": "https://api.github.com/repos/thenagain/opencv-xcframework/releases/assets/140864041",
"id": 140864041,
"node_id": "RA_kwDOK6Gkas4IZWop",
"name": "opencv2.xcframework-4.8.1.zip",
.
.
.
},
.
.
.
}
]
パッケージファイルの記述
アップロードしたファイルのGitHub API URLをパッケージファイルに記述します。
Swift Package Managerの場合
import PackageDescription
let version = "4.8.1"
let url = "https://api.github.com/repos/thenagain/opencv-xcframework/releases/assets/140864041.zip"
let sha256 = "44582a5486454e05d349d295cee520608ee9efe603b3305741fdf86e5c8754ad"
let package = Package(
name: "opencv2",
platforms: [
.iOS(.v13)
],
products: [
.library(
name: "opencv2",
targets: ["opencv2"]),
],
targets: [
.binaryTarget(name: "opencv2",
url: url,
checksum: sha256)
]
)
Package.swift
で注意したいこと
- URLの末尾に
.zip
を加える必要がある - checksumを記述する必要がある
swift package compute-checksum opencv2.xcframework-4.8.1.zip
CocoaPodsの場合
Pod::Spec.new do |spec|
spec.name = "opencv2"
spec.version = "4.8.1"
spec.summary = "OpenCV (Computer Vision) for iOS."
spec.description = "OpenCV: Open Source Computer Vision Library."
spec.homepage = "https://opencv.org"
spec.license = { :type => "Apache License, Version 2.0", :url => "https://www.apache.org/licenses/LICENSE-2.0" }
spec.authors = "https://github.com/opencv/opencv/graphs/contributors"
spec.platform = :ios, "13.0"
spec.source = {
:http => "https://api.github.com/repos/thenagain/opencv-xcframework/releases/assets/140864041",
:type => "zip",
:headers => ["Accept: application/octet-stream"]
}
spec.vendored_frameworks = "opencv2.xcframework"
end
.podspec
で注意したいこと
-
source
で:type => "zip"
と指定する -
source
で:headers => ["Accept: application/octet-stream"]
と指定する
(Optional) ドラフトリリースをパブリッシュする
パッケージファイルの変更とタグをgit push
したら、ドラフトで保存していたリリースを編集して、パブリッシュするとよいでしょう。
Organizationのプライベートリポジトリの場合、ドラフトリリースはWrite以上の権限を持っていないとアクセスすることができないからです1。
なお、ドラフトリリースをパブリッシュしてもRelease AssetsのGitHub API URLは変わらないので安心してください。
利用編
配布側に対して、利用側に必要な手順は簡潔です。
~/.netrc
の設定
プライベートリポジトリのRelease Assetsにアクセスするためには、personal access tokenによる認証が必要です。
Swift Package Manager・CocoaPodsともに~/.netrc
を参照してくれるため、~/.netrc
にその記述があれば、アクセスすることができます。
machine api.github.com
login thenagain
password ghp_XXXXXXXXXXXXXXXXXX
おわりに
XCFrameworkをサーバー上でホストする場合の選択肢はいろいろあると思いますが、この記事で紹介した方法のメリットは、利用側で必要なアクセス権をGitHubのリポジトリのみに絞れることだと思っています。ぜひ試してみてください。