CapacitorプラグインをSPM対応にマイグレーションする5ステップ
Capacitor iOSプラグインをCocoaPods対応だけではなく、SPMにも対応できるようマイグレーションしていきましょう。 SPMになぜ対応するのか、対応して何が嬉しいのかは以下をご覧ください。
1. プラグインファイル名を変更する
ここでいう「プラグインファイル」は、 ios/Plugin
以下にあるヘッダーファイルとmファイル、あとSwiftファイルの中でも @obj がついており、プラグインとして先頭に呼び出されるファイルを指しています。古いプラグイン構成だと、以下の構成となっています。
- Plugin.swift
- Plugin.m
- Plugin.h
これだとややこしいので、最近の構成である以下の構成にファイル名を変更します。 **
はプラグイン名で、例えばAdMobプラグインだと **Plugin.swift
は AdMobPlugin.swift
と読み替えてください。
- **Plugin.swift
- **Plugin.m
- **Plugin.h
ちなみに、最終的に Plugin.xcodeproj
等のファイルは全部削除するので、リンク先まで修正することを考えてXcode上でリネームする必要はありません。単純にファイル名を変更するだけで大丈夫です。続いて、 **Pugin.swift
を開いてみてください。 **Plugin
という名称になっていなかったら変更が必要です。
- @objc(Stripe)
- public class Plugin: CAPPlugin {
+ @objc(StripePlugin)
+ public class StripePlugin: CAPPlugin {
2. capacitor-plugin-converterで変換する
https://github.com/ionic-team/capacitor-plugin-converter を使って、自動変換できる部分は自動変換します。この操作自体はとても簡単なのですが、まず任意の場所で以下のコマンドでzipファイルをDLします。
% curl -OL https://github.com/ionic-team/capacitor-plugin-converter/releases/latest/download/cap2spm.zip
で、ダブルクリックするとUnix実行ファイルになりますので、これを実行します。例えば、この実行ファイルをダウンロードした場所から、マイグレーションしたいペイメントプラグインが相対的に ./payment
フォルダにあるとしましょう。上記の **.swift
の **
部分は PaymentPlugin
です。その場合、以下を実行します。
% ./cap2spm payment --no-backup
--no-backup
をつけないと、既存ファイルを .old
ファイルとしてリネームして置いといてくれますが、ほとんどの場合はGitでプラグイン管理しているので不要でしょう。これを実行すると、 **Plugin.h
と **Plugin.m
が削除され、その内容が **Plugin.swift
の pluginMethods
プロパティに移行されます。こんな感じで追加されると思ってください。
SPMはヘッダーファイルとmファイルを読み込まないので、このように移行しておく必要があります。あと、トップディレクトリに Package.swift
が自動生成されます。
3. プラグイン内で新規プラグインをつくる
いろいろ移行方法を考えたのですが、新規プラグインをつくって、 ios
フォルダをそのままコピーしてしまうのが一番問題がありません。新規プラグインをつくる方法は以下の通りです。
% cd payment # 今回の例だとpaymentフォルダというプラグインフォルダに移動したものとします
% npm init @capacitor/plugin@latest -- --package-id com.hoge.huga --repo https://example.com --author "hoge" --license MIT --description "hoge" ## プラグイン内にコピーするための新規プラグインをつくります
面倒なので、必要ない項目に関しては適当に入るようにコマンドを調整しています。これをすると、以下の項目を聞かれるので、ちゃんと入れてください。
✔ What should be the npm package of your plugin?
… 現行のプラグインのnpm名を入力してください
✔ What directory should be used for your plugin?
… プラグインフォルダ名。ここでは `new-template` としましょう。
✔ What should be the class name for your plugin?
… **Plugin.swift の "**" 部分を入力ください。
ちなみにファイル生成したあと npm install
が走りますが、別に途中で切ってしまって大丈夫です。
4. iOSフォルダを刷新
さて、構成を刷新していきます。 new-template
ディレクトリの使う部分を使い、以前の残すものを残していきます。なお、Web、Androidのコードはここでは変更を行わないので、間違って削除したり上書きしたりしないようにしてください。
new-template
を上書き
4.1. 既存のプラグインコードで まず、既存のプラグインコード(ios/plugins
の中身)を、 new-template/ios/Sources/**Plugin
ディレクトリに移動します。
new-template/ios
フォルダで既存の ios
フォルダを上書き
4.2. そうするともう不要ですので、既存の ios
フォルダを削除できます。今までのプラグインの ios
フォルダと随分構造が変わったので、(もちろん不要ファイルを削除してパスの指定をやり直してもいいんですが)、今後を考えてクリーンな形にしましょう。
既存の ios
フォルダを削除して、 new-template/ios
フォルダをその場所に配置しましょう。
new-template/Package.swift
で、トップディレクトリの Package.swift
を上書き
4.4. 2つめのステップで自動生成された Package.swift
ですが、新しくつくったほうで上書きしておきます。これはほとんどの場合において、マイグレーションツールよりも、新規作成の方がクリーンな構成であることが多いためです。
new-template/package.json
で、トップディレクトリの package.json
を上書き
4.5. package.json
も、新しくつくったほうで上書きしておきます。npmでリリースするための files
の内容が変わっているのと、あと古くから使っているプラグインだとdevDependencyも随分バージョンが変わっていたりします。少なくても、差分で何が変わっているかは確認しておいてください。
new-template
を削除
4.6 もう不要ですので、作成した new-template
ディレクトリ自体を削除します。
**.podspec
ファイルの更新
4.7. podspec
ファイルに、iOSのディレクトリ指定があるので、それを以下のように更新します。
- s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
+ s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
5. Package.swiftを更新
依存関係がある場合、 Package.swift
を更新する必要があります。例えば、 podspec
で以下の依存があったとしましょう。
s.dependency 'StripePaymentSheet', '~> 23.32.0'
s.dependency 'StripeApplePay', '~> 23.32.0'
その場合、これを Package.swift
でも書いておく必要があります。
dependencies: [
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", branch: "main"),
+ .package(url: "https://github.com/stripe/stripe-ios-spm.git", branch: "main")
],
targets: [
.target(
name: "StripePlugin",
dependencies: [
.product(name: "Capacitor", package: "capacitor-swift-pm"),
.product(name: "Cordova", package: "capacitor-swift-pm"),
+ .product(name: "StripePaymentSheet", package: "stripe-ios-spm"),
+ .product(name: "StripeApplePay", package: "stripe-ios-spm")
],
path: "ios/Sources/StripePlugin"),
パッケージマネージャーツールを2つ併用する必要があるため、今後パッケージを管理する上では podspec
と Package.swift
の両方を更新していく必要があることを覚えておいてください。
これでマイグレーションの終了です!
まとめ
capacitor-plugin-converterがもうちょっといろいろと自動でやってくれると幸せになれるのですが、まぁCapacitorプラグインの構成自体、長い期間にいろいろ試行錯誤されてきたので仕方ない部分もありますよね。フォルダをあっちにコピーしたり、こっちに移動したりとちょっとややこしくみえますが、何をどうマイグレーションするかを先にちゃんと頭にいれておくと単なる単純作業ですので、ぜひチャレンジしてみてください。
それではまた。
Discussion