ライブラリを使ったFlutter plugin開発のことはじめ iOS編
はじめに
私はこれまでお仕事を通じて、いくつかネイティブSDKをラップするFlutter pluginを開発してきました。
今回、その経験からライブラリ(xcframework)を使ったFlutter pluginを作成する方法をまとめました。ハマると厄介な落とし穴がありますので、そちらもお伝えします。
※ 以降xcframeworkバンドルをベースに記載しておりあますが、frameworkバンドルの場合は、xcframeworkをframeworkに置き換えていただければ動作するはずです。
環境
- Flutter: >=3.3 <=3.10.0
- CocoaPods: >=1.11.x <=1.12.1
- Xcode: >=13 <=14.3
作成方法
それでは、ABClient.xcframeworkというライブラリをラップするFlutter pluginを作成しましょう。
はじめに、以下のコマンドを実行します。
flutter create --org my.organization.abclient --template=plugin --platform=android,ios -a kotlin -i swift abclient_sdk
さて早速ですが、ここで重要なポイントがあります!
それは、Plugin nameを、abclient_sdkとしたことです。
Flutter pluginでXCFrameworkをラップするときは、Framework名とPlugin名を一緒にしてはいけない
Plugin作成時に絶対にやってはいけないことがあります。それは、Framework名をPlugin名と同じにすることです(case insensitive)。
例えば、ABClient.xcframeworkというSDKがある場合、Flutter pluginをabclientという名前で作成しないようにしましょう。
なぜ同じ名前ではダメなのか?
その理由は、abclientという名前でpluginを作成すると、内部でframework名の衝突が発生するからです💥 この衝突が発生するとアプリインストールが以下のようなエラーが発生してできなくなります。
「Details」を開くと以下のエラーメッセージが表示されます。
This application's bundle identifier does not match its code signing identifier.
このエラーは厄介なことに、上記の状況になってもビルドはできます。インストール時に初めて発覚するので一瞬何がおかしいのか検討がつかなくなり、戸惑うことになります。
なぜ名前の衝突が起こるのか?
なぜ名前の衝突が発生するのでしょうか?
これは、Flutterがpluginをアプリケーションに取り込む際にCocoaPodsを通じて内部でabclient.frameworkを作成することと関係していると推測しています。
このabclient.frameworkとABClient.xcframeworkから作成されるABClient.frameworkとが、case insensitiveで一致してしまうのです。
おそらくApplication bundleのcode signingは、同名のframework bundleが存在すると適切に実行されないのではないかと思われます。そのためインストール時の署名検証でエラーになってしまうのです。
よって、Flutterが内部で作成するframework名が衝突しないようにすればいいので、plugin名をFramework名と別名にすることで回避できます。
iosフォルダにxcframeworkを配置して、Podspecを編集する
さて、適切な名称のpluginを作成できたら、xcframeworkをiosフォルダに配置して、以下のようにPodspecファイルを編集します。
Pod::Spec.new do |s|
s.name = 'abclient_sdk'
...
s.source_files = 'Classes/**/*'
# === 以下を追加する =====
s.vendored_frameworks = 'ABClient.xcframework'
# ======================
s.dependency 'Flutter'
...
end
example/ios/Runner.xcworkwork
を準備する
この段階で一度以下のコマンドを実行します。これでRunner projectに諸々が生成されます。
cd example
flutter build ios
Xcode build done.
まで実行できたらOKです!(code sigingのエラーが発生したら、後で直しましょう)
次にexample/ios/Runner.xcworkspace
を開きます。
Pod projectの Development Pods > abclient_sdk > Frameworksに、ABClient.xcframeworkが配置されていることを確認できます。
準備完了です!
これで準備完了です。
..
を辿って行くと見つけられるAbclientSdkPlugin.swift
にimport ABClient
を追加してビルドができるようになっています。
あとはAbclientSdkPlugin.swift
やClassesフォルダに追加したファイルで実装していきましょう。
最後に
別の記事で、Androidのaarを使ったpluginを作成する方法を記載する予定です。
Discussion