cocoapods-to-spm について
Capacitor iOS アプリを CocoaPods から Swift Package Manager に移行するためのスキルです。ネイティブプロジェクトのカスタマイズを保ちながら、依存関係の確認、移行方法の選択、検証を進めます。
主な機能
- 01依存関係とカスタマイズの確認
- 02プラグインの SPM 対応状況の確認
- 03移行方法の選定
- 04CLI と Xcode の手順
- 05移行後の検証
- 06よくある問題のトラブルシューティング
活用シーン
- 01既存の Capacitor iOS アプリを SPM に移行
- 02移行を妨げるプラグインや Pod の特定
- 03拡張機能とネイティブ設定の維持
- 04移行後にプラグインが見つからない問題の診断
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ cap-go/ capgo-skills --skill cocoapods-to-spmインストール後、Claude Code で/cocoapods-to-spmを入力して読み込まれたか確認します。
同梱ファイルmetadata.jsonreferences/troubleshooting.md
詳細
CocoaPods から Swift Package Manager への移行
ネイティブプロジェクトのカスタマイズを失わずに、Capacitor の iOS アプリを CocoaPods から SPM に移行します。
使用するタイミング
次の場合に使用します:
ios/App/Podfile、Pods/、Podfile.lock、またはApp.xcworkspaceがあり、ユーザーが SPM を希望している場合。- ユーザーが
npx cap spm-migration-assistant、CapApp-SPM、debug.xcconfig、または--packagemanager SPMについて質問している場合。 - CocoaPods Trunk が読み取り専用になる見込み(2026 年 12 月 2 日)や、公開・更新できなくなった Pod についてユーザーが懸念している場合。
npx cap syncでSome installed Capacitor plugins are not compatible with SPMまたは<plugin id> does not have a Package.swiftという警告が表示される場合。- Capacitor 9 へのアップグレードと同時に CocoaPods を廃止したい場合。
次の場合は使用しないでください:
- 保守しているプラグインに
Package.swift/CAPBridgedPluginを追加する場合 ->capacitor-plugin-spm-support。 - SceneDelegate/UIScene の導入(Capacitor 8.5 以降、Xcode 27 で必須) ->
capacitor-uiscene-migration。 - Capacitor のメジャーアップグレードそのもの ->
capacitor-app-upgrades、capacitor-app-upgrade-v8-to-v9。 - 依存関係管理とは無関係なビルドまたは実行時の失敗 ->
debugging-capacitor。
なぜ今なのか
- CocoaPods Trunk は 2026 年 12 月 2 日 に読み取り専用になる見込みです。既存の Pod は引き続き解決されますが、新しい Pod バージョンは公開されなくなるため、プラグインの修正はますます SPM のみで提供されるようになります。
- Capacitor 8 以降では、新しい iOS プロジェクトはデフォルトで SPM を使って生成されます。Capacitor をアップグレードしても、既存の CocoaPods アプリは変換されません。
- Capacitor 9(現在は
next/アルファ版)では、Cordova プラグインがインストールされている場合に限り、Cordovaプロダクト/CapacitorCordovaPod が追加されます。Cordova プラグインなしでCordovaをインポートするネイティブコードは、どちらの構成でも動作しません。
CLI による判定方法
- CLI は、
ios/App/CapApp-SPM/が存在する場合に限り、プロジェクトを SPM として扱います。削除または名前変更すると、npx cap syncは何も通知せず CocoaPods の動作に戻ります。 ios/App/CapApp-SPM/Package.swiftは、npx cap sync iosのたびに再生成されます(// DO NOT MODIFY THIS FILE - managed by Capacitor CLI commands)。カスタマイズは必ずcapacitor.config.*に記述し、このファイルには加えないでください。- プラグインが含まれるのは、その npm パッケージのルートに
Package.swiftがある場合のみです。それ以外は警告とともにスキップされ、ネイティブコードは実行時に通知なく欠落します("X" plugin is not implemented on ios)。 - 同期時に、プラグインの
Package.swiftでcapacitor-swift-pmのメジャーバージョンが異なるものに固定されていると、CLI はnode_modules内のそのファイルを書き換え、<id> is built for Capacitor <N>, it might cause issuesと警告します。これは成功ではなく、「プラグインをアップグレードする必要がある」と判断してください。 - Cordova プラグインには、
ios/capacitor-cordova-ios-plugins/sources/<Name>にパッケージが生成されます。通常の.frameworkファイルは SPM のバイナリーターゲットとしてサポートされていません(警告:custom .framework files are not supported as binaryTarget in SPM)。.xcframeworkが必要です。
コマンドの方針
- インストールとスクリプトにはリポジトリのパッケージマネージャーを使用し、Capacitor CLI の呼び出しは
npx cap ...のままにして、プロジェクトローカルの CLI が実行されるようにしてください。 capacitor.config.*があるディレクトリからコマンドを実行してください。
ライブプロジェクトのスナップショット
検出された Capacitor、iOS、Cordova、プラグインの依存関係:
!node -e "const fs=require('fs');if(!fs.existsSync('package.json'))process.exit(0);const pkg=JSON.parse(fs.readFileSync('package.json','utf8'));const out=[];for(const section of ['dependencies','devDependencies']){for(const [name,version] of Object.entries(pkg[section]||{})){if(name.startsWith('@capacitor/')||name.startsWith('@capgo/')||name.startsWith('@capacitor-community/')||name.startsWith('@awesome-cordova-plugins/')||name.startsWith('cordova-')||name.includes('capacitor'))out.push(section+'.'+name+'='+version)}}console.log(out.sort().join('\n'))"
関連する iOS 依存関係ファイル:
!find ios -maxdepth 5 \( -name 'Podfile' -o -name 'Podfile.lock' -o -name 'Pods' -o -name 'App.xcworkspace' -o -name 'Package.swift' -o -name 'Package.resolved' -o -name 'CapApp-SPM' -o -name 'debug.xcconfig' -o -name 'project.pbxproj' -o -name 'Info.plist' -o -name '*.entitlements' -o -name 'GoogleService-Info.plist' \) 2>/dev/null
手順
1. 調査(読み取り専用)
package.jsonの Capacitor バージョン(@capacitor/ios)。8.x と 9.x はサポートされています。6.x/7.x の場合は、まずアップグレードすることをおすすめします。ios/App/PodfileとPodfile.lockを確認し、すべての Pod と、Capacitor プラグインではないもの(Firebase、分析 SDK、手動で追加したカスタム Pod)をリストアップします。- 各 Capacitor/Cordova プラグインについて、
node_modules/<pkg>/Package.swiftが存在するか確認します。Cordova プラグインにはパッケージが自動生成されるため、NOの項目のみが移行を妨げます:node -e "const fs=require('fs');const p=require('./package.json');for(const n of Object.keys({...p.dependencies,...p.devDependencies})){const d='node_modules/'+n;if(!fs.existsSync(d+'/ios')&&!fs.existsSync(d+'/plugin.xml'))continue;console.log((fs.existsSync(d+'/Package.swift')?'SPM ':fs.existsSync(d+'/plugin.xml')?'CORDOVA ':'NO ')+n)}" ios/App/App.xcodeproj/project.pbxprojの署名、カスタムビルド設定、追加ターゲット(ウィジェット、通知サービス拡張機能)、ビルドフェーズ、スキームを確認します。ios/App/App/のAppDelegate.swift、SceneDelegate.swift、Info.plist、エンタイトルメント、GoogleService-Info.plist、カスタム Swift/ObjC ファイルを確認します。
編集する前に、調査結果を報告します。SPM 非対応のプラグイン、SPM への置き換えが必要なプラグイン以外の Pod、リスクのあるネイティブのカスタマイズを提示してください。
2. ブロッカーを解消する
NO のプラグインまたはプラグイン以外の Pod ごとに、次の対応を行います:
- プラグインをアップグレードします。
@capacitor/*や@capgo/*を含む、メンテナンスされているプラグインの多くにはPackage.swiftが含まれています。 - メンテナンスされている SPM 対応の代替品に置き換えます。
- プロジェクトがプラグインを所有している場合は、
capacitor-plugin-spm-supportを使って変換します。 - Podfile に直接追加されたサードパーティ SDK の Pod は、移行後にベンダーの SPM パッケージを Xcode の App ターゲットに追加します。
重要なプラグインに SPM への移行手段がない場合は、続行する前にユーザーに確認してください。Podfile と CapApp-SPM を併用する構成は維持しないでください。
3. 方法を選択する
| 方法 | 使用する状況 |
|---|---|
npx cap spm-migration-assistant | ほとんどのアプリに適しています。既存の Xcode プロジェクトとそのカスタマイズを維持します。 |
| 新規スキャフォールド | ios/ がテンプレートに近い場合(拡張機能がなく、ネイティブの編集が少ない)。 |
| 手動修復 | アシスタントの実行が途中までだった場合、またはプロジェクトが大幅にカスタマイズされている場合。 |
4a. 移行アシスタントを実行する
まずコミットします。pod deintegrate が実行されるため、CocoaPods(または Bundler)が引き続きインストールされている必要があります。
npx cap spm-migration-assistant
pod deintegrate を実行し、Podfile、Podfile.lock、App.xcworkspace を削除して、ios/App/CapApp-SPM/ を展開します。さらに、ios/debug.xcconfig(CAPACITOR_DEBUG = true)を書き込み、Info.plist にない場合は CAPACITOR_DEBUG = $(CAPACITOR_DEBUG) を追加してから、Package.swift を生成する iOS アップデートを実行します。最後に To complete migration follow the manual steps at https://capacitorjs.com/docs/ios/spm#using-our-migration-tool と表示されます。
Xcode での手動操作が 2 つ残っています(npx cap open ios を実行すると、App.xcodeproj が開きます):
- Project
App-> Package Dependencies ->+-> Add Local... ->ios/App/CapApp-SPMを選択 -> Add Package の順に進み、CapApp-SPMライブラリをAppターゲットにリンクします。 - Project
App-> Info -> Configurations -> Debug に進み、構成ファイルとしてdebug.xcconfigを設定します。
その後、npx cap sync ios を実行します。
4b. 新規スキャフォールド
まず、ステップ 1.5 に記載されているすべての項目をバックアップしてください。
rm -rf ios
npx cap add ios --packagemanager SPM
npx cap sync ios
Capacitor 8.5 以降では、新しいテンプレートに SceneDelegate.swift と UIApplicationSceneManifest がすでに含まれています。アイコン、Info.plist のキー、エンタイトルメント、署名、Firebase plist、カスタムソース、拡張機能ターゲットは、テンプレートファイルを上書きせず、マージして復元してください。
5. capacitor.config.* でのオプションの SPM 設定
必要な場合にのみ設定してください(すべて experimental.ios.spm 配下にあり、インストール済みの CLI バージョンがサポートしていることを確認してください)。
swiftToolsVersion(8.3 以降、デフォルトは'5.9'):生成されるPackage.swiftのヘッダーです。packageTraits(8.3 以降):{ "<plugin id>": ["TraitName", ".defaults"] }。swiftToolsVersionが'6.1'以上である必要があります。packageOptions(8.4 以降):パッケージ名やモジュールの衝突に対する{ "<plugin id>": { symlink: true, moduleAliases: { "Target": "Alias" } } }です。
6. UIScene の確認
アシスタントが変更するのは依存関係の管理のみです。Info.plist に UIApplicationSceneManifest がない場合、アプリは Capacitor 8.5 以降と Xcode 27 が想定するシーンライフサイクルを使用していません。npx cap migrate を実行するか、capacitor-uiscene-migration に従ってください。
検証
# No CocoaPods leftovers
ls ios/App | grep -E 'Podfile|Pods|xcworkspace' && echo "LEFTOVERS" || echo "clean"
# CLI sees SPM and every plugin is included
npx cap sync ios 2>&1 | grep -Ei 'Package.swift|not compatible|built for Capacitor'
grep -c '.package(name:' ios/App/CapApp-SPM/Package.swift
# Plugin classes registered for runtime
node -e "console.log(require('./ios/App/App/capacitor.config.json').packageClassList)"
# Build without Xcode UI (project, not workspace)
xcodebuild -project ios/App/App.xcodeproj -scheme App -destination 'generic/platform=iOS Simulator' build
さらに Xcode で、CapApp-SPM が App ターゲットにリンクされていること、Debug で debug.xcconfig が使用されていること、署名/バンドル ID/機能が変更されていないことを確認してください。デバイス上で各ネイティブプラグイン(カメラ、プッシュ通知、購入など)を一度ずつ動作させてください。
ios/App/CapApp-SPM/ と ios/debug.xcconfig をコミットしてください。Package.resolved については CapApp-SPM/.gitignore に従ってください(新しいテンプレートでは無視されます)。
エラー処理
全項目の表については references/troubleshooting.md を読み込んでください。特によくあるケースは次のとおりです。
| メッセージ/症状 | 修正方法 |
|---|---|
Capacitor project is already using SPM, exiting. | CapApp-SPM/ がすでに存在しています。アシスタントではなく、手動で修復してください。 |
CocoaPods is not installed.(アシスタント) | CocoaPods を一時的にインストールするか、新規スキャフォールドの方法を使用してください。 |
<id> does not have a Package.swift / Some installed Capacitor plugins are not compatible with SPM | そのプラグインをアップグレード、置換、または変換してください(ステップ 2)。 |
実行時に "X" plugin is not implemented on ios | プラグインが Package.swift から除外されているか、packageClassList に含まれていません。プラグインを修正し、再同期して、クリーンビルドしてください。 |
No such module 'Capacitor' / Missing package product 'CapApp-SPM' | ローカルパッケージが追加またはリンクされていません。手動のステップ 1 をやり直し、次に File -> Packages -> Reset Package Caches を実行してください。 |
| Debug 限定の機能が動作しない(WebView の検査ができない、デバッグログが出ない) | Debug 構成に debug.xcconfig が設定されていません。 |
出力形式
計画については、現在の状態(Capacitor のバージョン、Pod、SPM 非対応のプラグイン、リスクのあるカスタマイズ)、選択した方法とその理由、順序付きの手順、Xcode/デバイスでのみ行う必要がある残りの確認事項を返してください。