CocoaPods のライブラリをGithub Releaseから取得するようにしてみた
おはようございます。waturaです。TALES iOSアプリネタの記事です。
この記事は note株式会社 Advent Calendar 2025 の 5日目の記事になります。
またあったねCocoaPods
TALESには広告SDKが入っています。
通常広告SDKはCocoaPodsで管理するのが一般的です。理由としては、メディエーションを提供しているGoogleのライブラリがCocoaPodsにしか対応していないためです。
別れを告げたのに、またあったね!しかもほぼフルSwiftUIでモダンな実装を目指してつくったアプリでまたあうなんてね!!ということで、CocoaPodsの話です。
やっぱりCocoaPods界隈オワコンでは。。。
今回、TALESアプリに組み込んだ一つのSDKの取得が、CI環境では不安定になり、CIがまともに動作しないという問題が発生しました。CIから使おうとすると、そのライブラリのCDNにアクセスできなくなるなんて,CIがない時代のライブラリなのでは?って思ってしまうようなCocoaPods界隈です。
今回は、そのCDNにつながらない対策をGithub Releaseをつかって行ないました。
基本的にはこれとかわらないような内容です。ただし、CocoaPodsです。というだけです。
GitHub Private repo で XCFramework を配布する zenn.dev
課題:CI環境でのSDK取得の不安定性
TALES iOSでは、SomeAdSDKという外部の広告SDKをつかっています。このSDKは公式CDN(cdn.example.com)から配信されているのですが、Xcode Cloud環境で問題が発生していました
DNS解決の失敗により、SDKのダウンロードが不安定
ビルド時にランダムに失敗し、開発フローが阻害される
ローカル環境では問題なく動作するため、原因の特定が困難
たぶん、Xcode Cloudからのアクセスがブロックされているんだろうなという理解です。
この問題を解決するため、GitHub ReleaseにSDKを保存し、CI環境からはGitHub経由で取得する仕組みを構築しました。
解決策:環境別のSDK取得元の切り替え
前述のZenn記事にあるようにGithub Release経由で取得するというのが、楽そうであると考えました。
JWTの作成やGITHUB Tokenをローカルでも扱う必要があるのですが、瑣末なSDKであり、また、ローカルから取得では失敗していないので
ローカル:公式CDN
CI: Github Release
と取得先を変更するようにしました。
1. GitHub Releaseへの自動アップロード
CIでつかえないので手元でしか動かせないという問題があるのですが,SDKの更新を自動化するスクリプトを作成しました。
#!/bin/bash
# 最新バージョンを取得
LATEST_VERSION=$(ruby -e "require 'cocoapods'; spec = Pod::Specification.from_file('親.podspec'); puts spec.dependencies.find { |d| d.name == 'SomeAdSDK' }.requirement.to_s")
# GitHub Releaseの存在確認
RELEASE_TAG="SomeAdSDK-v${VERSION}"
if gh release view "$RELEASE_TAG" &>/dev/null; then
echo "Release already exists"
exit 0
fi
# 公式CDNからダウンロード
curl -o "${TMP_DIR}/${FILENAME}" "https://cdn.example.com/release-sdk/ios/${VERSION}/${FILENAME}"
# GitHub Releaseを作成してアップロード
gh release create "$RELEASE_TAG" \
"${TMP_DIR}/${FILENAME}" \
--title "SomeAdSDK ${VERSION}" \
--notes "Mirrored from official CDN for CI stability"
# Github Release から asset urlを取得
ASSET_API_URL=$(gh release view "$RELEASE_TAG" --json assets --jq '.assets[0].apiUrl')
2. podspec
CocoaPodsのライブラリはpodspecというファイルで定義されています。Package.swiftのようなファイルです。
アップデートスクリプトで取得した,ASSET_API_URLをつかってGithubから取得するようにします。
また、GITHUB_TOKENはGithubアプリを作ってTOKEN取り出す別スクリプトとかでenvにいれるようにしています。
Pod::Spec.new do |s|
s.name = 'SomeAdSDK'
s.version = '20250930'
# CI環境ではGitHub Release Asset APIから取得
if ENV['CI'] && !ENV['CI'].to_s.empty? && ENV['GITHUB_TOKEN']
s.source = {
http: 'https://api.github.com/repos/org/repo/releases/assets/315017293',
type: 'zip',
headers: [
"Authorization: Bearer #{ENV['GITHUB_TOKEN']}",
'Accept: application/octet-stream'
]
}
# ローカル環境では公式CDNから取得
else
s.source = {
http: 'https://cdn.example.com/release-sdk/ios/20250930/SomeAdSDK.framework-20250930.zip'
}
end
s.vendored_frameworks = 'SomeAdSDK.framework'
end
3. Podfileでのカスタムpodspecの参照
# カスタムpodspecを使用(GitHub Releaseから取得)
# CI環境での公式CDNへのDNS解決問題を回避
pod 'SomeAdSDK', :podspec => 'SomeAdSDK.podspec'
まとめ
もうCocoaPodsは終わったんだよ?
CocoaPods Trunk Read-only Plan - CocoaPods Blog The blog for CocoaPods.org the Cocoa Dependency ManagerThe De blog.cocoapods.org
というところはともかくも、安定してCIが動くようになりました。
そもそも、他社は問題ないのか。もっとCocoaPodsの運用でイイ方法があるのかとかしりたいことはいろいろあります。が、動いているしもういいやという気分でもあります。
今後やりたいこととしては、今はTALES iOSのリポジトリのReleaseにいれているんですが、別リポジトリさっさとつくってしまいたいですね。
広告SDKのためにタグとかreleaseきりまくるのもいやだよねぇとなるのや、カオスになっちゃうのでというところが理由ですね。
#noteアドカレ2025