mcpField
C
capacitor-plugin-spm-support

capacitor-plugin-spm-support

github.com/cap-go開発75728 回インストール2 週間前に更新
リポジトリ

capacitor-plugin-spm-support について

capacitor-plugin-spm-support は、CocoaPods 対応を維持したまま Capacitor プラグインに Swift Package Manager 対応を追加するスキルです。メンテナー向けに、ソース変換、パッケージ設定、検証の手順を案内します。

主な機能

  1. 01SPM マニフェストとターゲット設定
  2. 02Swift プラグイン登録への変換
  3. 03CocoaPods podspec の維持
  4. 04依存関係とリソースの設定
  5. 05パッケージとアプリの検証

活用シーン

  1. 01SPM ベースのアプリへのプラグイン導入
  2. 02Package.swift 不在の警告への対応
  3. 03Capacitor 9 向けプラグイン配布の準備
  4. 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. 手動変換
  1. ソースを移動します:ios/Plugin/ -> ios/Sources/<ClassName>/、テスト -> ios/Tests/<ClassName>Tests/。
  2. クラスを変換します(メソッド名と戻り値の型は、.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() }
    }
    
  3. FooPlugin.m と FooPlugin.h(CAP_PLUGIN ブリッジ)、および ios/ 配下の古い Plugin.xcodeproj、Plugin.xcworkspace、Podfile、Info.plist ファイルを削除します。
  4. ルートに Package.swift を追加します。テンプレートとバリエーション(リソース、バイナリターゲット、サードパーティパッケージ、Swift と ObjC の混在)については references/package-swift-templates.md を参照してください。
  5. podspec を更新します:s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}' とし、s.dependency 'Capacitor' を維持し、デプロイメントターゲットとリソースを一致させます。
  6. 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 packagecapacitor-swift-pm 依存関係がないか、プロダクト名が間違っています。
public headers ("include") directory path for 'X' is invalid or not contained in the targetpublicHeadersPath のない 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 runtimeresources: を宣言し、Bundle.main ではなく Bundle.module を使用して読み込んでください。

リファレンス

トピックが関係する場合にのみ読み込んでください:

  • references/package-swift-templates.md:基本マニフェスト、リソースとプライバシーマニフェスト、サードパーティの SPM 依存関係、バイナリ .xcframework、Swift と ObjC の混在ターゲット、Capacitor 8 と 9 の依存関係ブロック。

コメント