capacitor-plugin-spm-support について
capacitor-plugin-spm-support は、CocoaPods 対応を維持したまま Capacitor プラグインに Swift Package Manager 対応を追加するスキルです。メンテナー向けに、ソース変換、パッケージ設定、検証の手順を案内します。
主な機能
- 01SPM マニフェストとターゲット設定
- 02Swift プラグイン登録への変換
- 03CocoaPods podspec の維持
- 04依存関係とリソースの設定
- 05パッケージとアプリの検証
活用シーン
- 01SPM ベースのアプリへのプラグイン導入
- 02Package.swift 不在の警告への対応
- 03Capacitor 9 向けプラグイン配布の準備
- 04SPM と CocoaPods のビルド確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ cap-go/ capgo-skills --skill capacitor-plugin-spm-supportインストール後、Claude Code で/capacitor-plugin-spm-supportを入力して読み込まれたか確認します。
同梱ファイルmetadata.jsonreferences/package-swift-templates.md
詳細
Capacitor プラグインに Swift Package Manager のサポートを追加する
CocoaPods アプリ向けの podspec を維持しながら、SPM ベースの Capacitor アプリにプラグインをインストールできるようにします。
使用するタイミング
次の場合に使用します。
- プラグインのリポジトリに
ios/Plugin/*.swiftと*.m/*.hがあり、CAP_PLUGIN(...)を含むものの、ルートにPackage.swiftがない。 - ユーザーが保守しているプラグインについて、アプリで
npx cap sync iosを実行すると<plugin id> does not have a Package.swiftと表示される。 - プラグインは CocoaPods では動作するものの、SPM アプリでは JS に
"X" plugin is not implemented on iosと表示される。 - Capacitor 9 または CocoaPods Trunk の読み取り専用化に備えてプラグインを準備する。
次の場合は使用しないでください。
- アプリ側の CocoaPods 削除 →
cocoapods-to-spm。 - プラグインの Capacitor メジャーバージョンのアップグレード →
capacitor-plugin-upgrades、capacitor-plugin-upgrade-v8-to-v9。 - Android のみのプラグイン作業、または Capacitor 以外(純粋な Cordova、React Native)のプラグイン。
CLI が適用するルール(注意が必要な点)
Package.swiftはios/の下ではなく、npm パッケージのルート(package.jsonと同じ階層)に置く必要があります。アプリの CLI がチェックするのは<plugin root>/Package.swiftのみです。- CLI はアプリの
CapApp-SPM/Package.swiftで、.package(name: "<Name>", path: ...)と.product(name: "<Name>", package: "<Name>")を使ってプラグインを参照します。ここで<Name>は npm の名前から生成されます。@を取り除き、/と-を単語の区切りとして PascalCase にします。@capgo/capacitor-updaterはCapgoCapacitorUpdaterに、@acme/capacitor-foo-barはAcmeCapacitorFooBarになります。Package(name:)と.library(name:)のプロダクト名は、どちらも<Name>と一致する必要があります。一致しない場合、アプリのビルドでプロダクトを解決できません。 - ランタイム登録では、
ios/App/App/capacitor.config.jsonのpackageClassListに、プラグインの iOS ソース(package.jsonのcapacitor.ios.src、既定値はios)をスキャンして取得した@objc(ClassName)が設定されます。クラスに@objc(<Class>Plugin)を残してください。これがないと、プラグインは登録されません。 capacitor-swift-pmの依存関係にはfrom: "<major>.0.0"を指定する必要があります。メジャーバージョンがアプリの Capacitor と異なる場合、アプリの同期処理がnode_modules内の値を書き換え、<id> is built for Capacitor <N>, it might cause issuesと警告します。- Capacitor 9 では、
.product(name: "Capacitor", package: "capacitor-swift-pm")のみに依存します。Cordovaプロダクトは無条件には含めないでください。これは Cordova プラグインをインストールしているアプリでのみ利用できます。コードが Cordova をインポートしている場合に限り、Capacitor 8 では残してください。
手順
1. 調査
package.json(name、files、capacitor.ios.src、スクリプト)、.podspec(s.name、s.ios.deployment_target、s.dependency、s.resources、s.vendored_frameworks)、ios/ 内のすべてのファイル、および .m ファイル内の CAP_PLUGIN(...) マクロを確認します。
次の項目を記録します。SPM の <Name>(上記のルールに従う)、クラス名、jsName、すべての CAP_PLUGIN_METHOD(name, returnType)、iOS のデプロイメントターゲット、サードパーティ製 pod、リソース、同梱フレームワーク、ブリッジ以外の ObjC/C ソース。
各サードパーティ製 pod に公式の SPM パッケージがあるか確認します。ないものがあれば、編集を始める前に報告し、削除するか、.xcframework として同梱するか、プラグインを CocoaPods のみの対応にするかをユーザーに確認してください。
2. 近道:コンバーター
iOS コードが [Name]Plugin.m/.h ブリッジ以外は Swift のみで構成されている場合は、公式コンバーターで大部分の作業を行えます(CAPBridgedPlugin の追加、Package.swift の作成、コードの ios/Sources と ios/Tests への移動、Plugin.xcodeproj/xcworkspace/Podfile の削除、podspec の source_files、files、verify:ios の更新)。差分を上記のルールと照合して確認してください。特にパッケージ名とプロダクト名に注意してください:https://github.com/ionic-team/capacitor-plugin-converter.
3. 手動変換
- ソースを移動します:
ios/Plugin/->ios/Sources/<ClassName>/、テスト ->ios/Tests/<ClassName>Tests/。 - クラスを変換します(メソッド名と戻り値の型は、
.mマクロのものをそのまま維持します):import Capacitor @objc(FooPlugin) public class FooPlugin: CAPPlugin, CAPBridgedPlugin { public let identifier = "FooPlugin" // first CAP_PLUGIN argument public let jsName = "Foo" // second CAP_PLUGIN argument (registerPlugin name) public let pluginMethods: [CAPPluginMethod] = [ CAPPluginMethod(name: "doThing", returnType: CAPPluginReturnPromise), CAPPluginMethod(name: "watch", returnType: CAPPluginReturnCallback), CAPPluginMethod(name: "fireAndForget", returnType: CAPPluginReturnNone) ] @objc func doThing(_ call: CAPPluginCall) { call.resolve() } } FooPlugin.mとFooPlugin.h(CAP_PLUGINブリッジ)、およびios/配下の古いPlugin.xcodeproj、Plugin.xcworkspace、Podfile、Info.plistファイルを削除します。- ルートに
Package.swiftを追加します。テンプレートとバリエーション(リソース、バイナリターゲット、サードパーティパッケージ、Swift と ObjC の混在)についてはreferences/package-swift-templates.mdを参照してください。 - podspec を更新します:
s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'とし、s.dependency 'Capacitor'を維持し、デプロイメントターゲットとリソースを一致させます。 package.jsonを更新します:files:ios/Sources/、Package.swiftを追加します。.podspecは維持し、古いios/Plugin/は削除します。verify:ios:xcodebuild -scheme <Name> -destination generic/platform=iOS
検証
# Package resolves and builds standalone (from plugin root)
swift package describe >/dev/null && echo "manifest ok"
xcodebuild -scheme <Name> -destination generic/platform=iOS build
# Published tarball contains the manifest and sources
npm pack --dry-run 2>&1 | grep -E 'Package.swift|ios/Sources'
# No leftover ObjC bridge
grep -rn "CAP_PLUGIN(" ios/ && echo "LEFTOVER BRIDGE"
次に、SPM のサンプル/テストアプリ(capacitor.config.* を含むディレクトリ)で、プラグインをインストールし(npm install ../path またはパッケージ化した tarball)、npx cap sync ios を実行します。does not have a Package.swift 警告が表示されないことを確認し、<Name> が ios/App/CapApp-SPM/Package.swift に表示されること、クラスが ios/App/App/capacitor.config.json の packageClassList に含まれることを確認してから、ビルドし、JS からメソッドを 1 つ呼び出します。podspec が引き続き公開されている場合は、pod lib lint(または CocoaPods のサンプルアプリ)も実行します。
エラー処理
| エラー | 修正方法 |
|---|---|
product '<Name>' required by package 'capapp-spm' target 'CapApp-SPM' not found in package '<Name>' | Package(name:) と .library(name:) が、CLI から導出された <Name> と一致していません。 |
"Foo" plugin is not implemented on ios | @objc(FooPlugin) がない、jsName が間違っている、またはクラスが packageClassList に含まれていません。修正後に再同期してください。 |
"Foo.bar()" is not implemented on ios | メソッドが pluginMethods にないか、@objc が付いていません。 |
No such module 'Capacitor' building the package | capacitor-swift-pm 依存関係がないか、プロダクト名が間違っています。 |
public headers ("include") directory path for 'X' is invalid or not contained in the target | publicHeadersPath のない ObjC 混在ターゲットです。ObjC を独立したターゲットに分割してください(リファレンスを参照)。 |
<id> is built for Capacitor <N>, it might cause issues (in app) | capacitor-swift-pm の from: をアプリのメジャーバージョンに合わせて引き上げてください。 |
Cordova product missing (Capacitor 9 app) | Cordova プロダクトの依存関係を削除してください。 |
| Resource not found at runtime | resources: を宣言し、Bundle.main ではなく Bundle.module を使用して読み込んでください。 |
リファレンス
トピックが関係する場合にのみ読み込んでください:
references/package-swift-templates.md:基本マニフェスト、リソースとプライバシーマニフェスト、サードパーティの SPM 依存関係、バイナリ.xcframework、Swift と ObjC の混在ターゲット、Capacitor 8 と 9 の依存関係ブロック。