Erste Schritte mit nativer Bibliotheks-Interoperabilität
Dieser Artikel beschreibt die ersten Schritte mit der nativen Bibliotheks-Interoperabilität mit Maui.NativeLibraryInterop zur Vereinfachung des Setups.
In diesen Anweisungen werden die grundlegenden Schritte, wichtigen Entscheidungspunkte und Leitbeispiele zum Erstellen von Bindungen über die native Bibliotheks-Interoperabilität beschrieben. Weitere Anleitungen zu spezifischen API- und Implementierungsdetails finden Sie in der Dokumentation zu den nativen SDKs und Bibliotheken von Interesse.
Voraussetzungen
Installieren von Voraussetzungen:
- .NET 9 SDK
- .NET MAUI-Workload (über Visual Studio oder CLI
dotnet workload install maui
) - Android SDK
- Android Studio
- Zielsetzung-Sharpie (für die manuelle Erstellung der C#-APIs)
- Xamarin.iOS (erforderlich, damit Objective-Sharpie funktioniert)
- Visual Studio oder Visual Studio Code
- Xcode
- Xcode-Befehlszeilentools (
xcode-select --install
)
Hinweis
Es ist möglich, das Android SDK und/oder die Xcode-Befehlszeilentools eigenständig zu installieren. Die Installation der Xcode-Befehlszeilentools wird jedoch in der Regel über Xcode abgewickelt. Ebenso wird die Android SDK-Installation in der Regel auch über Android Studio und/oder die .NET MAUI VS Code-Erweiterung gemäß der Dokumentation Erste Schritte mit .NET MAUI abgewickelt.
Erstellen einer neuen Bindung
Am einfachsten können Sie mit dem Erstellen einer neuen Bindung beginnen, indem Sie die Vorlage im Maui.NativeLibraryInterop-Repository klonen und dort Änderungen vornehmen. Um besser zu verstehen, wie Maui.NativeLibraryInterop derzeit aufgebaut ist, lesen Sie bitte die Übersichtsdokumentation.
Einrichten der .NET-Bindungsbibliotheken
Die Vorlage enthält Starter-Bindungsbibliotheken für .NET für Android und .NET für iOS.
Aktualisieren Sie die Bindungsbibliotheken, um die Zielplattformen und die .NET-Version in Ihrer .NET-App nach Bedarf widerzuspiegeln.
Hinweis
Beispiel: Wenn Sie nur eine iOS-Bindung mit .NET 9 erstellen möchten, können Sie Folgendes tun:
- Löschen Sie die Android-Bindungsbibliothek unter template/android/NewBinding.Android.Binding und
- Aktualisieren Sie das Zielframework unter template/macios/NewBinding.MaciOS.Binding/NewBinding.MaciOS.Binding.csproj auf
net9.0-ios
.
Einrichten der nativen Wrapperprojekte und -bibliotheken
Die Vorlage enthält auch Starter-Projekte für Android Studio und Xcode.
Aktualisieren Sie die nativen Projekte, um die Zielplattformen und -versionen in Ihrer .NET-App nach Bedarf widerzuspiegeln, und schließen Sie die nativen Bibliotheken von Interesse mit den folgenden Schritten ein.
Setup: iOS und Mac Catalyst
Das Xcode-Projekt befindet sich unter template/macios/native/NewBinding.
Aktualisieren Sie das Xcode-Projekt, um die Zielplattformen und -versionen widerzuspiegeln, so wie in Ihrer .NET-App unterstützt. Klicken Sie im Xcode-Projekt auf das Framework der obersten Ebene und führen Sie in Ziele > Allgemein Folgendes durch:
- Fügen Sie alle Supportziele nach Bedarf hinzu bzw. entfernen Sie diese.
- Passen Sie die iOS-Version nach Bedarf an.
Bringen Sie die native Bibliothek für iOS und/oder MacCatalyst in Ihr Xcode-Projekt ein, indem Sie die für Ihre Bibliothek und Ihre Anforderungen am besten geeignete Methode verwenden (z. B. CocoaPods, Swift Package Manager).
Setup: Android
Das Android Studio-Projekt befindet sich unter template/android/native.
Aktualisieren Sie das Android Studio-Projekt, um die in Ihrer .NET-App unterstützten Zielversionen widerzuspiegeln.
- Navigieren Sie zur Datei build.gradle.kts (:app)
- Aktualisieren Sie die
compileSdk
-Version nach Bedarf
Bringen Sie die native Android-Bibliothek über Gradle ein
- Fügen Sie die Paketabhängigkeit in den Abhängigkeitsblock der Datei build.gradle.kts (:app) ein.
- Fügen Sie in der Datei
dependencyResolutionManagement
dem Blockrepositories
das Repository hinzu. - Synchronisieren Sie das Projekt mit Gradle-Dateien (über die Schaltfläche in der oberen rechten Ecke von Android Studio).
Erstellen der API-Schnittstelle
Erstellen Sie die API-Schnittstelle zwischen Ihren nativen Projekten und Ihren .NET-Bindungsprojekten mit den folgenden Schritten.
API-Definition: iOS und Mac Catalyst
Nehmen Sie auf der nativen Seite Aktualisierungen in template/macios/native/NewBinding/NewBinding/DotnetNewBinding.swift vor:
- Fügen Sie eine Import-Anweisung hinzu, um die soeben von Ihnen hinzugefügte native Bibliothek zu importieren.
- Schreiben Sie die API-Definitionen für die nativen Bibliotheks-APIs von Interesse.
- Stellen Sie sicher, dass das Xcode-Projekt erfolgreich kompiliert wird und Sie mit den APIs zufrieden sind.
Zurück auf der .NET-Seite sind wir nun bereit, mit der nativen Bibliothek zu interagieren:
- Führen Sie
dotnet build
aus template/macios/NewBinding.MaciOS.Binding aus, um zu testen, ob alles richtig angeschlossen und einsatzbereit ist. - Verwenden Sie Objective Sharpie, um die C#-Bindungen für Ihre Swift-API-Aktualisierungen zu generieren.
- Navigieren Sie zu template/macios/NewBinding.MaciOS.Binding/bin/Debug/net9.0-ios/NewBinding.MaciOS.Binding.resources/NewBindingiOS.xcframework/ios-arm64/NewBinding.framework in Ihrem MaciOS-Bindungsprojekte-Ausgabeordner.
- Führen Sie
sharpie xcode -sdks
aus, um eine Liste der gültigen Ziel-SDK-Werte für den Bindungsbefehl abzurufen. Wählen Sie den Wert aus, der mit der Plattform und Version übereinstimmt, die Sie mit dem nächsten Befehl verwenden möchten, z. B.iphoneos18.0
. - Laufen lassen
sharpie bind
gegen die Header-Dateien im xcframework, das vom Bindungsprojekt erstellt wurde:sharpie bind --output=sharpie-out --namespace=NewBindingMaciOS --sdk=iphoneos18.0 --scope=Headers Headers/NewBinding-Swift.h
- Aktualisieren Sie den Inhalt von template/macios/NewBinding.MaciOS.Binding/ApiDefinition.cs durch den Inhalt von template/macios/NewBinding.MaciOS.Binding/bin/Debug/net9.0-ios/NewBinding.MaciOS.Binding.resources/NewBindingiOS.xcframework/ios-arm64/NewBinding.framework/sharpie-out/ApiDefinitions.cs und nach Belieben zu ändern (z. B. Benennung).
- Führen Sie
dotnet build
erneut aus template/macios/NewBinding.MaciOS.Binding aus.
Siehe auch die objektiv-scharf Dokumentation, um mehr über dieses Tool zu erfahren.
API-Definition: Android
Auf der nativen Seite nehmen Sie Aktualisierungen in template/android/native/newbinding/src/main/java/com/example/newbinding/DotnetNewBinding.java:
- Fügen Sie eine Import-Anweisung hinzu, um die soeben von Ihnen hinzugefügte native Bibliothek zu importieren.
- Schreiben Sie die API-Definitionen für die nativen Bibliotheks-APIs von Interesse.
- Stellen Sie sicher, dass das Android Studio-Projekt erfolgreich kompiliert wird und Sie mit den APIs zufrieden sind.
Zurück auf der .NET-Seite sind wir nun bereit, mit der nativen Bibliothek zu interagieren:
- Führen Sie
dotnet build
in template/android/NewBinding.Android.Binding aus, um zu testen, ob alles richtig angeschlossen und einsatzbereit ist. (Hinweis: Dieser Schritt erfordert, dass JDK 17 installiert ist) - Verweisen Sie auf alle Android-Binding-Abhängigkeiten, indem Sie ein
@(AndroidMavenLibrary)
Artikel zu Vorlage/Muster/MauiSample.csproj für jede Maven-Abhängigkeit, die in Ihrem nativen Android-Projekt eingebunden wird. Dadurch wird die Überprüfung von Java-Abhängigkeiten für Ihr Projekt aktiviert und führt dazu, dass nachfolgende Builds entweder Build-Warnungen oder Fehler wegen fehlender Abhängigkeiten generieren. Sie können diese Warnungen/Fehler beheben, indem Sie@(AndroidMavenLibrary)
oder@(PackageReference)
Elemente wie vorgeschlagen, um die Java-Abhängigkeitskette für die native Bibliothek, die Sie binden, zu erfüllen. (Hinweis: Die gradle/maven-Abhängigkeiten müssen oft explizit referenziert werden, da sie nicht automatisch in Ihre Bibliothek gebündelt werden).
<ItemGroup Condition="$(TargetFramework.Contains('android'))">
<AndroidMavenLibrary Include="{DependencyGroupId}:{DependencyName}" Version="{DependencyVersion}" Bind="false" />
</ItemGroup>
Siehe auch die AndroidMavenLibrary-Referenz und Überprüfung von Java-Abhängigkeiten Dokumentation für weitere Informationen zu diesem Prozess.
Hinweis
Sie können die Platzhalterklasse DotnetNewBinding
umbenennen, um die umschlossene native Bibliothek besser widerzuspiegeln. Weitere Beispiele und Tipps zum Schreiben der API-Definitionen finden Sie weiter unten im Abschnitt Ändern einer vorhandenen Bindung.
Nutzen der APIs in Ihrer .NET-App
Die Vorlage enthält eine .NET MAUI-Beispiel-App unter template/sample/MauiSample, die auf die .NET-Bindungsprojekte verweist und die nativen Bibliotheken sofort einsatzbereit macht!
Wenn Sie jedoch ihre eigenen .NET MAUI-, .NET für Android-, .NET für iOS- und/oder .NET für Mac Catalyst-Apps verwenden möchten, können Sie dies tun, indem Sie Ihre .NET-App-Projektdateien ändern, um auf die Bindungsbibliotheken zu verweisen:
<!-- Reference to MaciOS Binding project -->
<ItemGroup Condition="$(TargetFramework.Contains('ios')) Or $(TargetFramework.Contains('maccatalyst'))">
<ProjectReference Include="..\..\macios\NewBinding.MaciOS.Binding\NewBinding.MaciOS.Binding.csproj" />
</ItemGroup>
<!-- Reference to Android Binding project -->
<ItemGroup Condition="$(TargetFramework.Contains('android'))">
<ProjectReference Include="..\..\android\NewBinding.Android.Binding\NewBinding.Android.Binding.csproj" />
</ItemGroup>
Ändern einer vorhandenen Bindung
Wenn die vorhandene API-Oberfläche die Funktionalität, die Sie in Ihrem eigenen Projekt benötigen, nicht verfügbar macht, ist es an der Zeit, Ihre eigenen Änderungen vorzunehmen!
iOS und Mac Catalyst
Innerhalb des Xcode-Projekts finden Sie eine oder mehrere Swift-Dateien, welche die öffentliche API-Oberfläche für die Bindung definieren. Die register
-Methode für Firebase Messaging ist beispielsweise wie folgt definiert:
@objc(MauiFIRMessaging)
public class MauiFIRMessaging : NSObject {
@objc(register:completion:)
public static func register(apnsToken: NSData, completion: @escaping (String?, NSError?) -> Void) {
let data = Data(referencing: apnsToken);
Messaging.messaging().apnsToken = data
Messaging.messaging().token(completion: { fid, error in
completion(fid, error as NSError?)
})
}
// ...
}
Hinweis
Native Wrapper-API-Typen, die von der .NET-Bindung verwendet werden, müssen als public
deklariert und mit @objc(NameOfType)
annotiert werden, und Methoden müssen ebenfalls public
sein und können auch von ähnlichen @objc(methodName:parameter1:)
-Anmerkungen profitieren, bei denen der Name und die Parameter angegeben werden, die dazu beitragen, die Bindung zu beeinflussen, die Objective Sharpie generieren wird.
Sie können in dieser Methode sehen, dass die öffentliche API-Oberfläche nur Typen verwendet, die .NET für iOS bereits kennt: NSData
, String
, NSError
und ein Rückruf.
Im Firebase.MaciOS.Binding
-Projekt enthält die Datei ApiDefinitions.cs die Bindungsdefinition für diese native Wrapper-API:
using System;
using Foundation;
namespace Firebase
{
// @interface MauiFIRMessaging : NSObject
[BaseType (typeof(NSObject))]
interface MauiFIRMessaging
{
[Static]
[Export ("register:completion:")]
[Async]
void Register (NSData apnsToken, Action<string?, NSError?> completion);
// ...
}
Angenommen, Sie möchten eine Methode zum Aufheben der Registrierung hinzufügen. Der Swift-Code sähe in etwa so aus:
@objc(unregister:)
public static func unregister(completion: @escaping (NSError?) -> Void) {
// need delegate to watch for fcmToken updates
Messaging.messaging().deleteToken(completion: { error in
completion(error as NSError?)
})
}
Die andere Hälfte besteht darin, die Datei ApiDefinitions.cs im Bindungsprojekt zu aktualisieren, um diese neue Methode verfügbar zu machen. Es gibt zwei Möglichkeiten, wie Sie dies tun können:
- Sie können den erforderlichen Code manuell hinzufügen
- Nachdem Sie das Bindungsprojekt erstellt haben, können Sie das Objective-Sharpie-Tool ausführen, um eine ApiDefinitions.cs Datei. Sie können versuchen, die relevanten Änderungen aus dieser Datei zu finden und sie manuell herüber zu kopieren, oder Sie können versuchen, die gesamte Datei zu kopieren und sich den Diff anzusehen, um den Teil zu finden, den Sie benötigen.
In diesem Fall wären die Änderungen an ApiDefinitions.cs wie folgt:
[Static]
[Export("unregister:")]
[Async]
void UnRegister(Action completion);
Nachdem Sie diese Änderungen vorgenommen haben, können Sie das Bindungsprojekt neu kompilieren, und die neue API kann von Ihrem .NET MAUI-Projekt verwendet werden.
Hinweis
Bindungsprojekte für Mac/iOS verwenden keine Quellgeneratoren, so dass das Projektsystem und IntelliSense möglicherweise nicht über die neuen APIs Bescheid wissen, bis Sie das Bindungsprojekt neu kompiliert und die Projektmappe neu geladen haben, so dass die Projektreferenz die neuere Assembly aufnimmt. Ihr App-Projekt sollte trotz der IntelliSense-Fehler kompiliert werden.
Android
Innerhalb des Android Studio-Projekts finden Sie ein Modulverzeichnis, das eine Java-Datei enthält, welche die öffentliche API-Oberfläche für die Bindung definiert. Beispielsweise wird die initialize
-Methode für Facebook wie folgt definiert:
package com.microsoft.mauifacebook;
import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.util.Log;
import com.facebook.LoggingBehavior;
import com.facebook.appevents.AppEventsLogger;
public class FacebookSdk {
static AppEventsLogger _logger;
public static void initialize(Activity activity, Boolean isDebug) {
Application application = activity.getApplication();
if (isDebug) {
com.facebook.FacebookSdk.setIsDebugEnabled(true);
}
com.facebook.FacebookSdk.addLoggingBehavior(LoggingBehavior.APP_EVENTS);
AppEventsLogger.activateApp(application);
_logger = AppEventsLogger.newLogger(activity);
}
// ...
}
Sie können in dieser Methode sehen, dass die öffentliche API-Oberfläche nur Typen verwendet, die .NET für Android bereits kennt: Activity
und Boolean
.
Im Projekt Facebook.Android.Binding enthält die Datei Transforms/Metadata.xml nur einigen XML-Code, um zu beschreiben, wie der Java-Paketname (com.microsoft.mauifacebook
) einem mehr C#-freundlichen Namespace (Facebook
) zugeordnet wird. Im Allgemeinen sind Android-Bindungen zu diesem Zeitpunkt „automatischer“ als Mac/iOS, und Sie sollten nur selten Änderungen an diesen Transformationsdateien vornehmen müssen.
<metadata>
<attr path="/api/package[@name='com.microsoft.mauifacebook']" name="managedName">Facebook</attr>
</metadata>
Angenommen, Sie möchten eine Methode zum Protokollieren eines Ereignisses hinzufügen. Der Java-Code sähe in etwa so aus:
public static void logEvent(String eventName) {
_logger.logEvent(eventName);
}
Aufgrund dieser einfachen Änderung erfordert das Bindungsprojekt keine Aktualisierungen der Transforms/Metadata.xml oder anderen Dateien. Sie können das Binding-Projekt einfach neu kompilieren, und die neue API kann von Ihrem .NET MAUI-Projekt verwendet werden.
Hinweis
Bindungsprojekte für Android verwenden keine Quellgeneratoren, so dass das Projektsystem und IntelliSense möglicherweise nicht über die neuen APIs Bescheid wissen, bis Sie das Bindungsprojekt neu kompiliert und die Projektmappe neu geladen haben, so dass die Projektreferenz die neuere Assembly aufnimmt. Ihr App-Projekt sollte trotz der IntelliSense-Fehler kompiliert werden.
.NET MAUI Community Toolkit