Native Library Interop
概要
Native Library Interop (旧称 "Slim Binding") は、.NET MAUI アプリ (.NET for Android、.NET for iOS、.NET for Mac Catalyst アプリなど) でネイティブ SDK にアクセスするためのパターンを指します。 そのアイデアは、.NET から呼び出したいネイティブ SDK に対する簡略化された API サーフェスを持つ独自の抽象化または薄い "ラッパー" を作成することです。 このネイティブ "ラッパー" ライブラリ/フレームワーク プロジェクトは、Android Studio 内に Java/Kotlin を使用して、または Xcode 内に Objective-C/Swift を使用して作成されます。 このアプローチはその SDK の API サーフェスのごく一部しか必要としない場合に特に適していますが、より大きな API サーフェスを使用する場合でも同様に上手く機能します。
Native Library Interop を使用するタイミングと理由の理解
Native Library Interop は、ネイティブ ライブラリとの統合を行うための非常に効果的なアプローチですが、必ずしもあなたのプロジェクトにとって最適なものとは限りません。 一般的に、バインディングを既に維持していて、それを継続することが苦痛でないのなら、アプローチを変更する必要はありません。 ライブラリの API の広範な使用を必要とするプロジェクトや、.NET MAUI 開発者をサポートするベンダーにとっては、従来のバインディングの方が依然として適している場合があります。 ただし、Native Library Interop は多くの場合、理解、実装、保守がより簡単な代替手段を提供します。
Native Library Interop の主な利点は、単純な API サーフェスでの効率性です。 ラッパーに含まれるのが .NET がサポートするプリミティブ型だけである場合、既存のバインド ツールは、従来のバインディングでしばしば必要となる手動作業を最小限に抑えながら信頼性の高い定義を生成することができます。 これによってプロセスは単純になります。ラッパー API の実装は通常、SDK ドキュメントに従い、多くの場合ベンダー ドキュメントからの直接コピーが可能になるからです。
初期セットアップはより複雑になるかもしれませんが、基盤 SDK への更新の管理に必要となる手間は一般的に少なくなります。 多くの場合、更新作業はバージョンの調整とプロジェクトのリビルドだけで済みます。 API サーフェスまたは SDK で破壊的変更が発生した場合でも、ラッパー API サーフェスと .NET アプリケーションの使用方法は安定したままとなる可能性が高く、従来のバインディングと比較して必要になる調整は少なくなります。
要約すると、Native Library Interop には以下に示すいくつかの利点があります。
- ネイティブ言語とツールで SDK ドキュメントに従うことを簡略化する
- 機能するバインディングを作成するために必要となる手動作業を減らす
- メンテナンスを容易にし、必要な更新の頻度を減らす
- 基盤 SDK の変更からのアプリの分離度合を高める
(特に Android 上での) 依存関係チェーンの解決には従来のバインディングと同様の作業が必要になる場合もありますが、合理化された実装とメンテナンスの利点により、Native Library Interop は多くのプロジェクトにとって魅力的な選択肢となります。
Maui.NativeLibraryInterop の理解
Native Library Interop を介して作成されるバインディングを作成して保守する上での重要な課題は、ネイティブ プロジェクト、それらのネイティブ依存関係、ビルド出力、.NET Binding ライブラリ プロジェクトを手動で結合することです。 Maui.NativeLibraryInterop は、ユーザーが独自のアプリのニーズに合わせてサンプルをビルドしてカスタマイズすることでプロセスをすぐに開始できるようにします。
これには、MSBuild 呼び出しを通したビルド プロセスの一部の調整も含まれます。 次の事柄が関係します。
- ネイティブ SDK の依存関係の解決またはダウンロード
- ネイティブ スリム バインディング プロジェクトとその依存関係のビルド
- 必要なネイティブ アーティファクトの所定の作業ディレクトリへの移動
- バインディング ライブラリ プロジェクトの API 定義の生成
バインディング ビルド プロセスは、以下のように CommunityToolkit.Maui.NativeLibraryInterop.BuildTasks
NuGet パッケージをバインディング プロジェクトに追加することで、ネイティブ SDK の依存関係を取得してビルドするように拡張されます。
<ItemGroup>
<PackageReference Include="CommunityToolkit.Maui.NativeLibraryInterop.BuildTasks" Version="0.0.1-pre1" />
</ItemGroup>
Android バインディング プロジェクトでは、以下のようにネイティブ ラッパー Gradle プロジェクトを含むルート フォルダーを指す @(NLIGradleProjectReference)
項目を追加します。
<ItemGroup>
<NLIGradleProjectReference Include="../native" >
<ModuleName>newbinding</ModuleName>
<!-- Metadata applicable to @(AndroidLibrary) will be used if set, otherwise the following defaults will be used:
<Bind>true</Bind>
<Pack>true</Pack>
-->
</NLIGradleProjectReference>
</ItemGroup>
iOS バインディング プロジェクトでは、以下のようにネイティブ ラッパー Xcode プロジェクトを指す @(NLIXcodeProjectReference)
項目を追加します。
<ItemGroup>
<NLIXcodeProjectReference Include="../native/NewBinding/NewBinding.xcodeproj">
<SchemeName>NewBinding</SchemeName>
<SharpieNamespace>NewBinding</SharpieNamespace>
<SharpieBind>true</SharpieBind>
<!-- Metadata applicable to @(NativeReference) will be used if set, otherwise the following defaults will be used:
<Kind>Framework</Kind>
<SmartLink>true</SmartLink>
-->
</NLIXcodeProjectReference>
</ItemGroup>
Android バインディング プロジェクトは、Metadata.xml 変換ファイルを介して実装されたものなど、オプションの手動変更をすべて考慮に入れて、API 定義を自動的に生成します。
iOS バインディング ライブラリ プロジェクトには、明示的に定義された API を含める必要があります。 これを支援するために、結果のネイティブ フレームワーク上で Objective-Sharpie を自動的に実行して、そこに API 定義ファイル (ApiDefinition.cs) を生成できます。 これは、iOS バインディング プロジェクトによって使用される ApiDefintion.cs ファイルの作成と保守時に役立つ参照として機能します。
必要なネイティブ依存関係は、バインディング アセンブリに埋め込まれます。 .NET プロジェクトがネイティブ プロジェクトへの参照を追加する際に、ネイティブ依存関係はアプリ内に自動的に含められます。
.NET MAUI Community Toolkit