Slim Bindingアプローチについて
今回はSlim Bindingアプローチを題材に.NET iOS/Android, MAUIにおけるBinding Library事情についての話をします。(Slim Bindingアプローチの具体的な実装手順は割愛します)
Binding Libraryとは?
Slim Bindingアプローチは言ってしまえばBinding Libraryの作り方の一つです。ですので、まずはBinding Libraryについて簡単に説明します。
例えば、FirebaseやFacebookのSDKのようなiOS/Android向けのネイティブライブラリを使いたい時、これらをC#から呼べるようにラップしたものがBinding Libraryです。
技術的には.NET iOS/Androidが各OSのAPIを呼ぶのと同様の仕組みを利用しており、元ライブラリのAPIとC#を対応させるためにAPI定義やサポートクラスを用意する必要があります。 C#として使いやすいように工夫したり、自動生成された結果を調整することが必要で、元のライブラリの規模複雑さに比例して労力がかかります。
バインディング用のC#プロジェクト(以下、Bindingプロジェクト)を作成し、そこにAPI定義ファイルとネイティブライブラリを配置してBinding Libraryをビルドするというのが標準的な作り方です。
Slim Bindingと比較して、元のネイティブライブラリが備えるAPIを全てC#から使えるようにするアプローチは"フルバインディング"と呼ばれます。
Slim Bindingアプローチ
Slim BindingもBinding Libraryを作る方法の一つですが、API定義の作成を簡単にするために工夫されています。
まず、XcodeやAndroid Studioで目的のネイティブライブラリを使用するライブラリを作成します。そして、C#のBindingプロジェクトでは自作したネイティブライブラリをターゲットにします。
自作ネイティブライブラリで最小限のAPIを公開したり、C#に落とし込みやすい形にすることにより、Bindingプロジェクトでの作業がスムーズになります。
1つのアプリケーションがネイティブライブラリの全APIを使用することはまず無いため、このアプローチは理にかなっています。
Slim Bindingとそうでない作り方の違いはこの図のようになります。
Git Hub上の公式サンプルリポジトリ
Slim Bindingが上手くいくケース
なるべくライブラリの依存関係を浅くして、自分がコントロールできる部分を大きくしようとするとハマりやすくなります。
ネイティブライブラリのフル機能の提供するBinding Libraryとそれに依存するライブラリのエコシステムを活用するのは魅力的ですが、カバー範囲の広さ故にアップデートに時間がかかる傾向にあります。
例えば、Microsoftが提供するBinding Libraryを通してGoogle Firebaseの一部のコンポーネント(Cloud Messagingなど)を利用していた場合を考えてみてください。 元のFirebase SDKはサービスごとに細かく分かれていて、それを反映したBinding Libraryも複数に分かれています。そのため、一連のライブラリの更新作業が足並み揃えて完了するまで待たなければなりません。
もしも、Slim Bindingアプローチにより必要最小限の機能を自力でアップデートできるのであれば、ネイティブライブラリの更新をアプリケーションに素早く適用することも可能となるわけです。
Binding Libraryを取り巻く問題
特に「Binding Libraryに依存するライブラリ」を利用していたアプリケーションとって難しい状況が続きました。それにより、Slim Bindingによる自力解決を検討すべき時を迎えたと言えます。
Xamarin.iOSと.NET iOSのバイナリ非互換
.NET iOSでnint
やnuint
などの型がC#で正式にサポートされることになった影響で、Xamarin.iOS向けに作られたライブラリは.NET iOSで利用できないという問題が発生しました。
この件は、オーナーがモチベーションを失って更新が停止したライブラリの存在を浮き彫りにしました。
Xamarinのサポート終了における.NET(MAUI)化の際に対応が必須だったこともあり、ソースコードをフォークして自分でビルドし直して対処したプロジェクトもあるのではないでしょうか。
Microsoftによる保守が停止したBinding Library
Xamarin時代、Google、Facebookなど利用者の多いSDKライブラリについてはXamarin社がBinding Libraryを作ってくれていました。MicrosoftがXamarinを買収した後はMicrosoftがこれらの保守を引継ぎました。
困ったことにiOS版では2年ほど更新が停止状態にあります、Microsoftからのサポート終了宣言はありません。一方でSlim Bindingがフルバインディングより適切なアプローチであると説明されされています。つまりそういうことなのでしょう。
何故かAndroid版に関しては更新が継続されているのですが、何かしらの幸運(サポート可能な開発者が残っている、iOSよりもバインディングの負荷が低い?)に支えられた現状であると推測されます。もしこれが無くなった時にどうするべきかは一度検討しておいた方が良いでしょう。
AppleのPrivacy Manifest対応
Binding Library界隈で当たりがひときわ大きかった事件です。
Appleの新しいプライバシー要件でiOSアプリやライブラリにPrivacy Manifestという情報を含めることが必要となりました。2024年5月1日以降はこれに対応していないとアプリの新規登録やアップデートがリジェクトされる(かもしれない)という重大要件です。
Plugin.xxxのようなクロスプラットフォームライブラリに依存していた場合、Privacy Manifest対応には次のような作業が必要となります。
- ネイティブライブラリがPrivacy Manifest対応版をリリースする。
- 新しいネイティブライブラリを使って、新しいBinding Libraryをリリースする。
- 新しいBinding Libraryを使って、新しいクロスプラットフォームライブラリをリリース。
- 新しいクロスプラットフォームライブラリを使って.NET(MAUI)アプリをリリースする。
Binding Libraryが対応してくれないと後続が動き出せない訳ですが、先述の通り半公式と思われていたMicrosoftのBinding Libraryが更新停止状態だったのでissueが悲惨な状況でした。
(実は今のところライブラリのPrivacy Manifestは特に何も言われないおかげで何とかなっているアプリもあるのでは)
つまりどうするべきか?
身も蓋も無い言い方をすると、Microsoftが半公式的なBinding Libraryの維持に限界を迎え、Slim Bindingによる自力解決を提案している状況です。
まずはライブラリの依存関係を把握しましょう。
アプリが依存しているライブラリ、ライブラリが依存しているライブラリを調査します。Binding Libraryが含まれていなければひとまず気にすべきことはありません。
直接的にBinding Libraryを利用していた場合
ライブラリの保守状況を確認します。 更新が望めず代替ライブラリも無い場合はSlim Bindingで対処する必要があります。
間接的にBinding Libraryを利用していた場合
Plugin.xxxのようなライブラリがBinding Libraryに依存していて、Binding Libraryの代わりにSlim Bindingで対処する場合の想定です。
プラグインで利用していた機能を自力で実装できるならそれが一番シンプルな解決法でしょう。 プラグイン全体が必要な場合、ソースコードを取り込んだ上でBinding Libraryに依存していた部分をSlim Bindingで作るライブラリが提供するように変更する方法が考えられます。今のところ試す機会はありませんでしたが、自分ならそうすると思います。(それが許されるかどうかはライセンスによるので確認してください)
関連情報
Slim Bindingアプローチのサンプル
Xamarin.Firebase.iOS.*のサポートに関する議論
Xamarin.Firebase.iOS.*ライブラリ群を引き継いでフォーク版を公開している方がいます。
Binding Library関連ドキュメント(iOS)
- iOS ライブラリのバインド - Xamarin | Microsoft Learn
- iOS Swift ライブラリのバインド - Xamarin | Microsoft Learn
- Xamarin.iOS バインド プロジェクトの移行 - .NET MAUI | Microsoft Learn
Binding Library関連ドキュメント(Android)
フォローしませんか?
お気軽にご依頼・ご相談ください