Komma igång med Interop för internt bibliotek
Den här artikeln beskriver hur du kommer igång med Native Library Interop med hjälp av Maui.NativeLibraryInterop för att förenkla installationen.
De här anvisningarna beskriver de grundläggande stegen, viktiga beslutspunkter och vägledande exempel för att skapa bindningar via interop för inbyggt bibliotek. Mer information om specifika API: er och implementeringsinformation finns i dokumentationen för interna SDK:er och bibliotek av intresse.
Förutsättningar
Installationskrav:
- .NET 9 SDK
-
.NET MAUI-arbetsbelastning (via Visual Studio eller CLI
dotnet workload install maui
) - Android SDK
- Android Studio
-
Objective-Sharpie (används för att manuellt generera C#-API:er)
- Xamarin.iOS- (krävs för att Objective-Sharpie ska fungera)
- Visual Studio eller Visual Studio Code
- Xcode
-
Xcode-kommandoradsverktyg (
xcode-select --install
)
Notera
Det går att installera Android SDK och/eller Xcode-kommandoradsverktyg fristående. Installationen av Xcode-kommandoradsverktygen hanteras vanligtvis via Xcode-. På samma sätt hanteras Android SDK- installation vanligtvis via Android Studio- och/eller .NET MAUI VS Code-tillägget enligt dokumentationen om .NET MAUI Komma igång.
Skapa en ny bindning
Det enklaste sättet att komma igång med att skapa en ny bindning är genom att klona mallen i Maui.NativeLibraryInterop lagringsplats och göra ändringar därifrån. Mer information om hur Maui.NativeLibraryInterop är konfigurerat finns i översiktsdokumentationen .
Konfigurera .NET-bindningsbiblioteken
Mallen innehåller startbibliotek för .NET för Android och .NET för iOS-bindningar.
Uppdatera bindningsbiblioteken så att de återspeglar målplattformarna och .NET-versionen efter behov i .NET-appen.
Notera
Exempel: Om du bara vill skapa en iOS-bindning med .NET 9 kan du:
- Ta bort Android-bindningsbiblioteket på template/android/NewBinding.Android.Bindingoch
- Uppdatera målramverket i template/macios/NewBinding.MaciOS.Binding/NewBinding.MaciOS.Binding.csproj för att ställa in till
net9.0-ios
.
Konfigurera de inbyggda omslagsprojekten och biblioteken
Mallen innehåller även Android Studio-startprojekt och Xcode-projekt.
Uppdatera de interna projekten så att de återspeglar målplattformarna och versionerna efter behov i .NET-appen och inkludera de inbyggda biblioteken med följande steg.
Konfiguration: iOS & Mac Catalyst
Xcode-projektet finns på template/macios/native/NewBinding.
Uppdatera Xcode-projektet så att det återspeglar målplattformarna och versionerna som stöds i .NET-appen. I Xcode-projektet klickar du på ramverket på den översta nivån och i Mål > Allmänt:
- Lägg till/ta bort alla supportmål efter behov.
- Justera iOS-versionen efter behov.
Ta in det inbyggda biblioteket för iOS och/eller MacCatalyst i ditt Xcode-projekt, genom vilken metod som passar bäst för ditt bibliotek och dina behov (t.ex. CocoaPods, Swift Package Manager).
Konfiguration: Android
Android Studio-projektet finns på template/android/native.
Uppdatera Android Studio-projektet så att det återspeglar de målversioner som stöds i .NET-appen.
- Navigera till filen build.gradle.kts (:app)
- Uppdatera den
compileSdk
versionen efter behov
Använd det inbyggda Android-biblioteket via Gradle
- Lägg till paketberoendet i beroendeblocket i build.gradle.kts (:app) fil.
- Lägg till lagringsplatsen i
dependencyResolutionManagement
repositories
-blocket i filen settings.gradle.kts. - Synkronisera projektet med gradle-filer (via knappen i det övre högra hörnet av Android Studio).
Skapa API-gränssnittet
Skapa API-gränssnittet mellan dina interna projekt och dina .NET-bindningsprojekt med följande steg.
API-definition: iOS & Mac Catalyst
På den inhemska sidan gör du uppdateringar i template/macios/native/NewBinding/NewBinding/DotnetNewBinding.swift:
- Lägg till en importinstruktion för att importera det inbyggda biblioteket som du nyss lade till.
- Skriv API-definitionerna för de interna biblioteks-API:erna av intresse.
- Kontrollera att Xcode-projektet kompileras utan problem och att du är nöjd med API:erna.
På .NET-sidan är vi nu redo att interoperera med det ursprungliga biblioteket.
- Kör
dotnet build
från template/macios/NewBinding.MaciOS.Binding för att testa att allt är ordentligt anslutet och redo att köra. - Använd objective sharpie för att generera C#-bindningar för dina Swift API-uppdateringar:
- Gå till template/macios/NewBinding.MaciOS.Binding/bin/Debug/net9.0-ios/NewBinding.MaciOS.Binding.resources/NewBindingiOS.xcframework/ios-arm64/NewBinding.framework i output-mappen för dina MaciOS-bindningsprojekt.
- Kör
sharpie xcode -sdks
för att hämta en lista över giltiga mål-SDK-värden för bindningskommandot. Välj det värde som överensstämmer med den plattform och version som du vill använda med nästa kommando, till exempeliphoneos18.0
. - Kör
sharpie bind
mot huvudfilerna i xcframework som skapats av bindningsprojektet:sharpie bind --output=sharpie-out --namespace=NewBindingMaciOS --sdk=iphoneos18.0 --scope=Headers Headers/NewBinding-Swift.h
- Uppdatera innehållet i template/macios/NewBinding.MaciOS.Binding/ApiDefinition.cs genom att ersätta det med innehållet i template/macios/NewBinding.MaciOS.Binding/bin/Debug/net9.0-ios/NewBinding.MaciOS.Binding.resources/NewBindingiOS.xcframework/ios-arm64/NewBinding.framework/sharpie-out/ApiDefinitions.cs och justera efter önskemål (t.ex. namngivning).
- Kör
dotnet build
från template/macios/NewBinding.MaciOS.Binding igen.
Mer information om det här verktyget finns i dokumentationen objective-sharpie.
API-definition: Android
På den native sidan, gör uppdateringar i template/android/native/newbinding/src/main/java/com/example/newbinding/DotnetNewBinding.java:
- Lägg till en importinstruktion för att importera det inbyggda biblioteket som du nyss lade till.
- Skriv API-definitionerna för de interna biblioteks-API:erna av intresse.
- Se till att Android Studio-projektet byggs framgångsrikt och att du är nöjd med API:erna.
På .NET-sidan är vi nu redo att interoperera med det ursprungliga biblioteket.
- Kör
dotnet build
från template/android/NewBinding.Android.Binding för att testa att allt är korrekt anslutet och redo. (Obs! Det här steget kräver att du har JDK 17 installerat) - Referera till alla Android-bindningsberoenden genom att lägga till ett
@(AndroidMavenLibrary)
objekt i mall/sample/MauiSample.csproj för varje maven-beroende som är bundet i ditt interna Android-projekt. Detta aktiverar Java-beroendeverifiering för projektet och gör att efterföljande versioner skapar byggvarningar eller fel för saknade beroenden. Du kan åtgärda dessa varningar/fel genom att lägga till@(AndroidMavenLibrary)
- eller@(PackageReference)
-elementen enligt förslagen för att uppfylla java-beroendekedjan för det inhemska biblioteket som du länkar. (Obs! Gradle/maven-beroenden måste ofta anges uttryckligen, eftersom de inte paketeras automatiskt i ditt bibliotek.)
<ItemGroup Condition="$(TargetFramework.Contains('android'))">
<AndroidMavenLibrary Include="{DependencyGroupId}:{DependencyName}" Version="{DependencyVersion}" Bind="false" />
</ItemGroup>
Se även AndroidMavenLibrary-referensen och dokumentationen för Java-beroendeverifiering för mer information om denna process.
Notera
Du kan byta namn på platshållaren DotnetNewBinding
-klassen för att bättre återspegla det interna bibliotek som hanteras. Fler exempel och tips för att skriva API-definitionerna finns i avsnittet nedan: Ändra en befintlig bindning.
Använd API:erna i din .NET-app
Den mallen innehåller en .NET MAUI-exempelapp vid mall/sample/MauiSample. Den refererar till .NET-bindningsprojekten och gör de inhemska biblioteken omedelbart redo att användas.
Om du är intresserad av att använda dina egna .NET MAUI-, .NET för Android-, .NET för iOS- och/eller .NET för Mac Catalyst-appar kan du dock göra det genom att ändra dina .NET-appprojektfiler så att de refererar till bindningsbiblioteken:
<!-- 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>
Ändra en befintlig bindning
Om den befintliga API-ytan inte exponerar de funktioner du behöver i ditt eget projekt är det dags att göra egna ändringar!
iOS & Mac Catalyst
I Xcode-projektet hittar du en eller flera Swift-filer som definierar den offentliga API-ytan för bindningen. Till exempel definieras register
-metoden för Firebase Messaging som:
@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?)
})
}
// ...
}
Notera
Inbyggda omslutnings-API-typer som ska användas av .NET-bindningen måste deklareras som public
och måste märkas med @objc(NameOfType)
, och metoder måste också vara public
, och kan också dra nytta av liknande anteckningar @objc(methodName:parameter1:)
där namn och parametrar anges vilka hjälper till att påverka bindningen som objektiv sharpie genererar.
I den här metoden kan du se att den offentliga API-ytan endast använder typer som .NET för iOS redan känner till: NSData
, String
, NSError
och ett återanrop.
I Firebase.MaciOS.Binding
-projektet innehåller ApiDefinitions.cs-filen bindningsdefinitionen för det här interna omslutnings-API:et:
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);
// ...
}
Anta att du vill lägga till en metod för avregistrering. Swift-koden skulle se ut ungefär så här:
@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?)
})
}
Den andra hälften är att uppdatera ApiDefinitions.cs-filen i bindningsprojektet för att exponera den nya metoden. Det finns två sätt att göra detta på:
- Du kan lägga till nödvändig kod manuellt
- När du har skapat bindningsprojektet kan du köra verktyget objective sharpie för att generera en ApiDefinitions.cs fil. Du kan försöka hitta relevanta ändringar från den här filen och kopiera dem manuellt, eller prova att kopiera över hela filen och titta på diff för att hitta den del du behöver.
I det här fallet skulle ändringarna i ApiDefinitions.cs vara:
[Static]
[Export("unregister:")]
[Async]
void UnRegister(Action completion);
När du har gjort de här ändringarna kan du återskapa bindningsprojektet och det nya API:et är redo att användas från ditt .NET MAUI-projekt.
Notera
Bindningsprojekt för Mac/iOS använder inte källgeneratorer, så projektsystemet och intellisense kanske inte känner till de nya API:erna förrän du har återskapat bindningsprojektet och läst in lösningen igen så att projektreferensen hämtar den nyare sammansättningen. Appprojektet bör fortfarande kompileras oavsett intellisense-fel.
Android
I Android Studio-projektet hittar du en modulkatalog som innehåller en java-fil som definierar den offentliga API-ytan för bindningen. Till exempel definieras metoden initialize
för Facebook enligt nedan:
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);
}
// ...
}
I den här metoden kan du se att den offentliga API-ytan endast använder typer som .NET för Android redan känner till: Activity
och Boolean
.
I projektet Facebook.Android.Binding innehåller filen Transforms/Metadata.xml endast en xml-fil som beskriver hur du mappar java-paketnamnet (com.microsoft.mauifacebook
) till ett mer C#-eget namnområde (Facebook
). I allmänhet är Android-bindningar mer "automatiska" än Mac/iOS just nu, och du bör sällan behöva göra ändringar i dessa transformeringsfiler.
<metadata>
<attr path="/api/package[@name='com.microsoft.mauifacebook']" name="managedName">Facebook</attr>
</metadata>
Anta att du vill lägga till en metod för att logga en händelse. Java-koden skulle se ut ungefär så här:
public static void logEvent(String eventName) {
_logger.logEvent(eventName);
}
Från den här enkla ändringen kräver bindningsprojektet inga uppdateringar av Transforms/Metadata.xml eller andra filer. Du kan helt enkelt återskapa bindningsprojektet och det nya API:et är redo att användas från ditt .NET MAUI-projekt.
Notera
Bindningsprojekt för Android använder inte källgeneratorer, så projektsystemet och intellisense kanske inte känner till de nya API:erna förrän du har återskapat bindningsprojektet och läst in lösningen igen så att projektreferensen hämtar den nyare sammansättningen. Appprojektet bör fortfarande kompileras oavsett intellisense-fel.
.NET MAUI Community Toolkit