Exemplarische Vorgehensweise: Binden einer iOS-Bibliothek Objective-C

Wichtig

Wir untersuchen derzeit die Nutzung benutzerdefinierter Bindungen auf der Xamarin-Plattform. Nehmen Sie an dieser Umfrage teil, um zukünftige Entwicklungsarbeiten zu unterstützen.

Dieser Artikel enthält eine praktische exemplarische Vorgehensweise zum Erstellen einer Xamarin.iOS-Bindung für eine vorhandene Objective-C Bibliothek, InfColorPicker. Es behandelt Themen wie das Kompilieren einer statischen Objective-C Bibliothek, das Binden und die Verwendung der Bindung in einer Xamarin.iOS-Anwendung.

Bei der Arbeit an iOS können Fälle auftreten, in denen Sie eine Drittanbieterbibliothek Objective-C nutzen möchten. In diesen Situationen können Sie ein Xamarin.iOS-Bindungsprojekt verwenden, um eine C#-Bindung zu erstellen, mit der Sie die Bibliothek in Ihren Xamarin.iOS-Anwendungen nutzen können.

Im Allgemeinen im iOS-Ökosystem finden Sie Bibliotheken in drei Varianten:

  • Als vorkompilierte statische Bibliotheksdatei mit .a Erweiterung zusammen mit den Header(n) (H-Dateien). Beispielsweise die Analysebibliothek von Google
  • Als vorkompiliertes Framework. Dies ist nur ein Ordner, der die statische Bibliothek, Kopfzeilen und manchmal zusätzliche Ressourcen mit .framework Erweiterung enthält. Beispielsweise die AdMob-Bibliothek von Google.
  • Ebenso wie Quellcodedateien. Beispielsweise eine Bibliothek, die nur .m und .h Objective C-Dateien enthält.

Im ersten und zweiten Szenario wird bereits eine vorkompilierte CocoaTouch Static Library vorhanden sein, daher konzentrieren wir uns in diesem Artikel auf das dritte Szenario. Denken Sie daran, dass Sie vor dem Erstellen einer Bindung immer die mit der Bibliothek bereitgestellte Lizenz überprüfen, um sicherzustellen, dass Sie es binden können.

Dieser Artikel enthält eine schrittweise exemplarische Vorgehensweise zum Erstellen eines Bindungsprojekts mithilfe des Open Source InfColorPicker-ProjektsObjective-C als Beispiel, aber alle Informationen in diesem Leitfaden können für die Verwendung mit jeder Drittanbieterbibliothek Objective-C angepasst werden. Die InfColorPicker-Bibliothek bietet einen wiederverwendbaren Ansichtscontroller, der es dem Benutzer ermöglicht, eine Farbe basierend auf seiner HSB-Darstellung auszuwählen, wodurch die Farbauswahl benutzerfreundlicher wird.

Example of the InfColorPicker library running on iOS

Wir behandeln alle erforderlichen Schritte, um diese bestimmte Objective-C API in Xamarin.iOS zu nutzen:

  • Zunächst erstellen wir eine Objective-C statische Bibliothek mit Xcode.
  • Anschließend binden wir diese statische Bibliothek mit Xamarin.iOS.
  • Als Nächstes zeigen Sie, wie Objective Sharpie die Arbeitsauslastung reduzieren kann, indem automatisch einige (aber nicht alle) der erforderlichen API-Definitionen generiert werden, die von der Xamarin.iOS-Bindung benötigt werden.
  • Schließlich erstellen wir eine Xamarin.iOS-Anwendung, die die Bindung verwendet.

Die Beispielanwendung veranschaulicht, wie sie eine starke Stellvertretung für die Kommunikation zwischen der InfColorPicker-API und unserem C#-Code verwenden. Nachdem wir gesehen haben, wie sie eine starke Stellvertretung verwenden, wird erläutert, wie schwache Stellvertretungen zum Ausführen derselben Aufgaben verwendet werden.

Anforderungen

In diesem Artikel wird davon ausgegangen, dass Sie sich mit Xcode und der Objective-C Sprache vertraut machen und unsere Bindungsdokumentation Objective-C gelesen haben. Darüber hinaus ist Folgendes erforderlich, um die dargestellten Schritte auszuführen:

  • Xcode und iOS SDK – Apples Xcode und die neueste iOS-API müssen auf dem Computer des Entwicklers installiert und konfiguriert werden.
  • Xcode-Befehlszeilentools – Die Xcode-Befehlszeilentools müssen für die derzeit installierte Version von Xcode installiert sein (siehe unten, details zur Installation).
  • Visual Studio für Mac oder Visual Studio – Die neueste Version von Visual Studio für Mac oder Visual Studio sollte auf dem Entwicklungscomputer installiert und konfiguriert werden. Ein Apple Mac ist für die Entwicklung einer Xamarin.iOS-Anwendung erforderlich, und wenn Sie Visual Studio verwenden, müssen Sie mit einem Xamarin.iOS-Buildhost verbunden sein.
  • Die neueste Version von Objective Sharpie - Eine aktuelle Kopie des Objective Sharpie-Tools heruntergeladen von hier. Wenn Sie Objective Sharpie bereits installiert haben, können Sie sie mithilfe der sharpie update

Installieren der Xcode-Befehlszeilentools

Wie oben erwähnt, verwenden wir die Xcode-Befehlszeilentools (speziell make und lipo) in dieser exemplarischen Vorgehensweise. Der make Befehl ist ein sehr gängiges Unix-Dienstprogramm, das die Kompilierung ausführbarer Programme und Bibliotheken mithilfe einer Makefile automatisiert, die angibt, wie das Programm erstellt werden soll. Der lipo Befehl ist ein Befehlszeilenprogramm für OS X zum Erstellen von Dateien mit mehreren Architekturen. Er kombiniert mehrere .a Dateien in einer Datei, die von allen Hardwarearchitekturen verwendet werden kann.

Laut apple es Building from the Command Line with Xcode FAQ documentation, in OS X 10.9 and greater, the Downloads pane of Xcode Preferences dialog not longer supports the downloading command-line tools.

Sie müssen eine der folgenden Methoden verwenden, um die Tools zu installieren:

  • Installieren Sie Xcode – Wenn Sie Xcode installieren, wird es mit allen Ihren Befehlszeilentools gebündelt. In OS X 10.9-Shims (installiert in /usr/bin) kann jedes Tool, das in /usr/bin Xcode enthalten ist, dem entsprechenden Tool zugeordnet werden. Beispielsweise der xcrun Befehl, mit dem Sie ein beliebiges Tool innerhalb von Xcode über die Befehlszeile suchen oder ausführen können.

  • Die Terminalanwendung – Über die Terminalanwendung können Sie die Befehlszeilentools installieren, indem Sie den xcode-select --install Befehl ausführen:

    • Starten Sie die Terminalanwendung.
    • Geben Sie die EINGABETASTE ein, und drücken Sie xcode-select --install die EINGABETASTE, z. B.:
    Europa:~ kmullins$ xcode-select --install
    
    • Sie werden aufgefordert, die Befehlszeilentools zu installieren, klicken Sie auf die Schaltfläche "Installieren ": Installing the command line tools

    • Die Tools werden von Apples Servern heruntergeladen und installiert: Downloading the tools

  • Downloads für Apple-Entwickler – Das Paket "Befehlszeilentools" ist auf der Webseite "Downloads für Apple-Entwickler " verfügbar. Melden Sie sich mit Ihrer Apple-ID an, und suchen Sie dann nach den Befehlszeilentools, und laden Sie sie herunter: Finding the Command Line Tools

Nachdem die Befehlszeilentools installiert wurden, können wir mit der exemplarischen Vorgehensweise fortfahren.

Exemplarische Vorgehensweise

In dieser exemplarischen Vorgehensweise werden die folgenden Schritte behandelt:

  • Erstellen einer statischen Bibliothek – Dieser Schritt umfasst das Erstellen einer statischen Bibliothek des InfColorPicker-CodesObjective-C. Die statische Bibliothek verfügt über die .a Dateierweiterung und wird in die .NET-Assembly des Bibliotheksprojekts eingebettet.
  • Erstellen Sie ein Xamarin.iOS-Bindungsprojekt – Sobald wir über eine statische Bibliothek verfügen, verwenden wir es, um ein Xamarin.iOS-Bindungsprojekt zu erstellen. Das Bindungsprojekt besteht aus der statischen Bibliothek, die wir soeben erstellt haben, und Metadaten in Form von C#-Code, in der erläutert wird, wie die Objective-C API verwendet werden kann. Diese Metadaten werden häufig als API-Definitionen bezeichnet. Wir verwenden Objective Sharpie , um uns bei der Erstellung der API-Definitionen zu helfen.
  • Normalisieren Sie die API-Definitionen - Objective Sharpie leistet eine großartige Aufgabe, uns zu helfen, aber es kann nicht alles tun. Wir besprechen einige Änderungen, die wir an den API-Definitionen vornehmen müssen, bevor sie verwendet werden können.
  • Verwenden Sie die Bindungsbibliothek – Schließlich erstellen wir eine Xamarin.iOS-Anwendung, um zu zeigen, wie sie unser neu erstelltes Bindungsprojekt verwenden.

Nachdem wir nun verstehen, welche Schritte erforderlich sind, fahren wir mit dem Rest der exemplarischen Vorgehensweise fort.

Erstellen einer statischen Bibliothek

Wenn wir den Code für InfColorPicker in Github prüfen:

Inspect the code for InfColorPicker in Github

Die folgenden drei Verzeichnisse werden im Projekt angezeigt:

  • InfColorPicker – Dieses Verzeichnis enthält den Objective-C Code für das Projekt.
  • PickerSamplePad – Dieses Verzeichnis enthält ein iPad-Beispielprojekt.
  • PickerSample Telefon – Dieses Verzeichnis enthält ein Beispiel für i Telefon Projekt.

Laden wir das InfColorPicker-Projekt von GitHub herunter und entzippen es im Verzeichnis unserer Wahl. Beim Öffnen des Xcode-Ziels für PickerSamplePhone das Projekt sehen wir die folgende Projektstruktur im Xcode Navigator:

The project structure in the Xcode Navigator

Dieses Projekt erreicht die Wiederverwendung von Code durch direktes Hinzufügen des InfColorPicker-Quellcodes (im roten Feld) zu jedem Beispielprojekt. Der Code für das Beispielprojekt befindet sich im blauen Feld. Da dieses bestimmte Projekt uns keine statische Bibliothek zur Verfügung stellt, ist es erforderlich, dass wir ein Xcode-Projekt erstellen, um die statische Bibliothek zu kompilieren.

Der erste Schritt besteht darin, dass wir den InfoColorPicker-Quellcode zur statischen Bibliothek hinzufügen. Um dies zu erreichen, gehen wir wie folgt vor:

  1. Starten Sie Xcode.

  2. Wählen Sie im Menü "Datei" die Option "Neues>Projekt" aus...

    Screenshot shows Project selected from the New menu of the File menu.

  3. Wählen Sie "Framework & Bibliothek", die Vorlage "Cocoa Touch Static Library " aus, und klicken Sie auf die Schaltfläche "Weiter ":

    Select the Cocoa Touch Static Library template

  4. Geben Sie InfColorPicker den Projektnamen ein, und klicken Sie auf die Schaltfläche "Weiter":

    Enter InfColorPicker for the Project Name

  5. Wählen Sie einen Speicherort aus, um das Projekt zu speichern, und klicken Sie auf die Schaltfläche "OK ".

  6. Jetzt müssen wir die Quelle aus dem InfColorPicker-Projekt zu unserem statischen Bibliotheksprojekt hinzufügen. Da die Datei "InfColorPicker.h " bereits in unserer statischen Bibliothek vorhanden ist (standardmäßig), lässt Xcode es nicht zu, sie zu überschreiben. Navigieren Sie vom Finder zum Quellcode von InfColorPicker im ursprünglichen Projekt, das wir von GitHub entzippt haben, kopieren Sie alle InfColorPicker-Dateien, und fügen Sie sie in unser neues statisches Bibliotheksprojekt ein:

    Copy all of the InfColorPicker files

  7. Kehren Sie zu Xcode zurück, klicken Sie mit der rechten Maustaste auf den Ordner "InfColorPicker" , und wählen Sie "InfColorPicker..." aus:

    Adding files

  8. Navigieren Sie im Dialogfeld "Dateien hinzufügen" zu den soeben kopierten InfColorPicker-Quellcodedateien, wählen Sie sie aus, und klicken Sie auf die Schaltfläche "Hinzufügen ":

    Select all and click the Add button

  9. Der Quellcode wird in unser Projekt kopiert:

    The source code will be copied into the project

  10. Wählen Sie im Xcode Project Navigator die Datei InfColorPicker.m aus, und kommentieren Sie die letzten beiden Zeilen aus (aufgrund der Art und Weise, wie diese Bibliothek geschrieben wurde, wird diese Datei nicht verwendet):

    Editing the InfColorPicker.m file

  11. Wir müssen nun überprüfen, ob für die Bibliothek Frameworks erforderlich sind. Sie finden diese Informationen entweder in der INFODATEI oder durch Öffnen eines der bereitgestellten Beispielprojekte. In diesem Beispiel werden sie verwendet Foundation.framework, UIKit.frameworkund CoreGraphics.framework wir fügen sie hinzu.

  12. Wählen Sie die InfColorPicker-Zielbuildphasen > aus, und erweitern Sie den Abschnitt "Binärdatei mit Bibliotheken verknüpfen":

    Expand the Link Binary With Libraries section

  13. Verwenden Sie die + Schaltfläche, um das Dialogfeld zu öffnen, mit dem Sie die oben aufgeführten erforderlichen Framesframeframeworks hinzufügen können:

    Add the required frames frameworks listed above

  14. Der Abschnitt "Binärdatei mit Bibliotheken verknüpfen" sollte nun wie die folgende Abbildung aussehen:

    The Link Binary With Libraries section

An diesem Punkt sind wir nah, aber wir sind nicht ganz fertig. Die statische Bibliothek wurde erstellt, aber wir müssen sie erstellen, um eine Fat-Binärdatei zu erstellen, die alle erforderlichen Architekturen für iOS-Geräte und iOS-Simulator enthält.

Erstellen einer Fett-Binärdatei

Alle iOS-Geräte verfügen über Prozessoren, die von der ARM-Architektur betrieben werden, die sich im Laufe der Zeit entwickelt haben. Jede neue Architektur hat neue Anweisungen und andere Verbesserungen hinzugefügt, während die Abwärtskompatibilität weiterhin Standard. iOS-Geräte verfügen über armv6, armv7, armv7s, arm64-Anweisungssätze – obwohl armv6 nicht mehr verwendet wird. Der iOS-Simulator wird nicht von ARM unterstützt und ist stattdessen ein x86 und x86_64 angetriebener Simulator. Das bedeutet, dass Bibliotheken für jeden Anweisungssatz bereitgestellt werden müssen.

Eine Fat-Bibliothek enthält .a alle unterstützten Architekturen.

Das Erstellen einer Fett-Binärdatei ist ein dreistufiger Prozess:

  • Kompilieren Sie eine ARM 7 & ARM64-Version der statischen Bibliothek.
  • Kompilieren Sie eine x86- und x84_64-Version der statischen Bibliothek.
  • Verwenden Sie das lipo Befehlszeilentool, um die beiden statischen Bibliotheken in einer zu kombinieren.

Obwohl diese drei Schritte ziemlich einfach sind, kann es erforderlich sein, sie in Zukunft zu wiederholen, wenn die Objective-C Bibliothek Updates empfängt oder wenn wir Fehlerkorrekturen benötigen. Wenn Sie sich dafür entscheiden, diese Schritte zu automatisieren, wird es die zukünftige Standard Tenance und Unterstützung des iOS-Bindungsprojekts vereinfachen.

Es gibt viele Tools zum Automatisieren solcher Aufgaben – ein Shellskript, rake, xbuild und make. Wenn die Xcode-Befehlszeilentools installiert sind, make wird auch installiert, d. h. das Buildsystem, das für diese exemplarische Vorgehensweise verwendet wird. Hier ist eine Makefile , mit der Sie eine gemeinsam genutzte Multiarchitekturbibliothek erstellen können, die auf einem iOS-Gerät und dem Simulator für jede Bibliothek funktioniert:

XBUILD=/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild
PROJECT_ROOT=./YOUR-PROJECT-NAME
PROJECT=$(PROJECT_ROOT)/YOUR-PROJECT-NAME.xcodeproj
TARGET=YOUR-PROJECT-NAME

all: lib$(TARGET).a

lib$(TARGET)-i386.a:
	$(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphonesimulator -configuration Release clean build
	-mv $(PROJECT_ROOT)/build/Release-iphonesimulator/lib$(TARGET).a $@

lib$(TARGET)-armv7.a:
	$(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphoneos -arch armv7 -configuration Release clean build
	-mv $(PROJECT_ROOT)/build/Release-iphoneos/lib$(TARGET).a $@

lib$(TARGET)-arm64.a:
	$(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphoneos -arch arm64 -configuration Release clean build
	-mv $(PROJECT_ROOT)/build/Release-iphoneos/lib$(TARGET).a $@

lib$(TARGET).a: lib$(TARGET)-i386.a lib$(TARGET)-armv7.a lib$(TARGET)-arm64.a
	xcrun -sdk iphoneos lipo -create -output $@ $^

clean:
	-rm -f *.a *.dll

Geben Sie die Makefile-Befehle im Nur-Text-Editor Ihrer Wahl ein, und aktualisieren Sie die Abschnitte mit "YOUR-PROJECT-NAME " mit dem Namen Ihres Projekts. Es ist auch wichtig sicherzustellen, dass Sie die obigen Anweisungen genau einfügen, wobei die Registerkarten in den Anweisungen erhalten bleiben.

Speichern Sie die Datei mit dem Namen Makefile an demselben Speicherort wie die statische InfColorPicker Xcode-Bibliothek, die wir oben erstellt haben:

Save the file with the name Makefile

Öffnen Sie die Terminalanwendung auf Ihrem Mac, und navigieren Sie zum Speicherort Ihrer Makefile. Geben Sie in das Terminal ein, drücken Sie make die EINGABETASTE, und die Makefile wird ausgeführt:

Sample makefile output

Wenn Sie den Text ausführen, sehen Sie einen großen Teil des Textlaufs. Wenn alles ordnungsgemäß funktioniert hat, werden die Wörter BUILD ERFOLGREICH angezeigt, und libInfColorPickerSDK.a die libInfColorPicker-armv7.alibInfColorPicker-i386.a Dateien werden an denselben Speicherort kopiert wie die Makefile:

The libInfColorPicker-armv7.a, libInfColorPicker-i386.a and libInfColorPickerSDK.a files generated by the Makefile

Sie können die Architekturen in Ihrer Fat-Binärdatei mithilfe des folgenden Befehls bestätigen:

xcrun -sdk iphoneos lipo -info libInfColorPicker.a

Dies sollte Folgendes anzeigen:

Architectures in the fat file: libInfColorPicker.a are: i386 armv7 x86_64 arm64

An diesem Punkt haben wir den ersten Schritt unserer iOS-Bindung abgeschlossen, indem wir eine statische Bibliothek mit Xcode und den Xcode-Befehlszeilentools make erstellen.lipo Gehen wir zum nächsten Schritt und verwenden Objective-Sharpie , um die Erstellung der API-Bindungen für uns zu automatisieren.

Erstellen eines Xamarin.iOS-Bindungsprojekts

Bevor wir Objective-Sharpie verwenden können, um den Bindungsprozess zu automatisieren, müssen wir ein Xamarin.iOS Binding Project erstellen, um die API-Definitionen zu speichern (die wir objective-Sharpie verwenden, um uns beim Erstellen zu helfen) und die C#-Bindung für uns zu erstellen.

Gehen wir wie folgt vor:

  1. Starten Sie Visual Studio für Mac.

  2. Wählen Sie im Menü "Datei" die Option "Neue>Lösung" aus...

    Starting a new solution

  3. Wählen Sie im Dialogfeld "Neue Projektmappe" "Bibliothek>iOS-Bindungsprojekt" aus:

    Select iOS Binding Project

  4. Klicken Sie auf die Schaltfläche Weiter.

  5. Geben Sie "InfColorPickerBinding" als Projektnamen ein, und klicken Sie auf die Schaltfläche "Erstellen ", um die Projektmappe zu erstellen:

    Enter InfColorPickerBinding as the Project Name

Die Lösung wird erstellt, und zwei Standarddateien werden eingeschlossen:

The solution structure in the Solution Explorer

  • ApiDefinition.cs – Diese Datei enthält die Verträge, die definieren, wie Objective-C API in C# umschlossen wird.
  • Structs.cs – Diese Datei enthält alle Strukturen oder Enumerationswerte, die von den Schnittstellen und Delegaten benötigt werden.

Wir arbeiten später in der exemplarischen Vorgehensweise mit diesen beiden Dateien zusammen. Zuerst müssen wir die InfColorPicker-Bibliothek zum Bindungsprojekt hinzufügen.

Einschließen der statischen Bibliothek im Bindungsprojekt

Jetzt haben wir unser Basisbindungsprojekt bereit, wir müssen die Fett-Binärbibliothek hinzufügen, die wir oben für die InfColorPicker-Bibliothek erstellt haben.

Führen Sie die folgenden Schritte aus, um die Bibliothek hinzuzufügen:

  1. Klicken Sie mit der rechten Maustaste auf den Ordner "Native Verweise" im Lösungskreuz, und wählen Sie "Native Verweise hinzufügen" aus:

    Add Native References

  2. Navigieren Sie zu der fetten Binärdatei, die wir zuvor erstellt haben (libInfColorPickerSDK.a) und drücken Sie die Schaltfläche "Öffnen ":

    Select the libInfColorPickerSDK.a file

  3. Die Datei wird in das Projekt eingeschlossen:

    Including a file

Wenn die A-Datei dem Projekt hinzugefügt wird, legt Xamarin.iOS automatisch die Buildaktion der Datei auf ObjcBindingNativeLibrary fest und erstellt eine spezielle Datei namens libInfColorPickerSDK.linkwith.cs.

Diese Datei enthält das LinkWith Attribut, das Xamarin.iOS angibt, wie die statische Bibliothek behandelt wird, die wir soeben hinzugefügt haben. Der Inhalt dieser Datei wird im folgenden Codeausschnitt angezeigt:

using ObjCRuntime;

[assembly: LinkWith ("libInfColorPickerSDK.a", SmartLink = true, ForceLoad = true)]

Das LinkWith Attribut identifiziert die statische Bibliothek für das Projekt und einige wichtige Linkerkennzeichnungen.

Als Nächstes müssen wir die API-Definitionen für das InfColorPicker-Projekt erstellen. Für diese exemplarische Vorgehensweise verwenden wir Objective Sharpie, um die Datei ApiDefinition.cs zu generieren.

Verwenden von Objective Sharpie

Objective Sharpie ist ein Befehlszeilentool (bereitgestellt von Xamarin), das beim Erstellen der definitionen helfen kann, die zum Binden einer Drittanbieterbibliothek Objective-C an C# erforderlich sind. In diesem Abschnitt verwenden wir Objective Sharpie, um die anfängliche ApiDefinition.cs für das InfColorPicker-Projekt zu erstellen.

Um zu beginnen, laden wir die Objective Sharpie-Installationsprogrammdatei wie in diesem Handbuch beschrieben herunter. Führen Sie das Installationsprogramm aus, und folgen Sie allen Bildschirmaufforderungen des Installations-Assistenten, um Objective Sharpie auf unserem Entwicklungscomputer zu installieren.

Nachdem Objective Sharpie erfolgreich installiert wurde, starten wir die Terminal-App, und geben Sie den folgenden Befehl ein, um Hilfe zu allen Tools zu erhalten, die sie zur Unterstützung der Bindung bereitstellt:

sharpie -help

Wenn der obige Befehl ausgeführt wird, wird die folgende Ausgabe generiert:

Europa:Resources kmullins$ sharpie -help
usage: sharpie [OPTIONS] TOOL [TOOL_OPTIONS]

Options:
  -h, --helpShow detailed help
  -v, --versionShow version information

Available Tools:
  xcode              Get information about Xcode installations and available SDKs.
  pod                Create a Xamarin C# binding to Objective-C CocoaPods
  bind               Create a Xamarin C# binding to Objective-C APIs
  update             Update to the latest release of Objective Sharpie
  verify-docs        Show cross reference documentation for [Verify] attributes
  docs               Open the Objective Sharpie online documentation

Im Rahmen dieser exemplarischen Vorgehensweise verwenden wir die folgenden Objective Sharpie-Tools:

  • xcode - Diese Tools geben uns Informationen über unsere aktuelle Xcode-Installation und die Versionen von iOS- und Mac-APIs, die wir installiert haben. Wir verwenden diese Informationen später, wenn wir unsere Bindungen generieren.
  • bind - Wir verwenden dieses Tool, um dieH-Dateien im InfColorPicker-Projekt in die ursprünglichen Dateien "ApiDefinition.cs" und "StructsAndEnums.cs" zu analysieren.

Um Hilfe zu einem bestimmten Objective Sharpie-Tool zu erhalten, geben Sie den Namen des Tools und die -help Option ein. Gibt beispielsweise sharpie xcode -help die folgende Ausgabe zurück:

Europa:Resources kmullins$ sharpie xcode -help
usage: sharpie xcode [OPTIONS]+

Options:
  -h, -help           Show detailed help
  -v, -verbose        Be verbose with output

Xcode Options:
  -sdks               List all available Xcode SDKs. Pass -verbose for more
                        details.
  -sdkpath SDK        Output the path of the SDK
  -frameworks SDK     List all available framework directories in a given SDK.

Bevor wir den Bindungsprozess starten können, müssen wir Informationen zu unseren aktuellen installierten SDKs abrufen, indem wir den folgenden Befehl in das Terminal sharpie xcode -sdkseingeben:

amyb:Desktop amyb$ sharpie xcode -sdks
sdk: appletvos9.2    arch: arm64
sdk: iphoneos9.3     arch: arm64   armv7
sdk: macosx10.11     arch: x86_64  i386
sdk: watchos2.2      arch: armv7

Von oben aus können wir sehen, dass das iphoneos9.3 SDK auf unserem Computer installiert ist. Mit diesen Informationen können wir die InfColorPicker-Projektdateien .h in die anfängliche ApiDefinition.cs und StructsAndEnums.cs für das InfColorPicker-Projekt analysieren.

Geben Sie den folgenden Befehl in die Terminal-App ein:

sharpie bind --output=InfColorPicker --namespace=InfColorPicker --sdk=[iphone-os] -scope [full-path-to-project]/InfColorPicker/InfColorPicker [full-path-to-project]/InfColorPicker/InfColorPicker/*.h

Wo [full-path-to-project] befindet sich der vollständige Pfad zum Verzeichnis, in dem sich die InfColorPicker Xcode-Projektdatei auf unserem Computer befindet, und [iphone-os] ist das iOS-SDK, das wir installiert haben, wie vom sharpie xcode -sdks Befehl erwähnt. Beachten Sie, dass wir in diesem Beispiel *.h als Parameter übergeben haben, der alle Headerdateien in diesem Verzeichnis enthält . Normalerweise sollten Sie dies nicht tun, sondern lesen Sie stattdessen sorgfältig die Headerdateien, um die H-Datei der obersten Ebene zu finden, die auf alle anderen relevanten Dateien verweist, und übergeben Sie dies einfach an Objective Sharpie.

Tipp

Übergeben Sie für das -scope Argument den Ordner mit den Kopfzeilen, die Sie binden möchten. Ohne das -scope Argument versucht Objective Sharpie, Bindungen für alle importierten iOS SDK-Header zu generieren, z. B. #import <UIKit.h>eine riesige Definitionsdatei, die beim Kompilieren des Bindungsprojekts wahrscheinlich Fehler generiert. Mit dem -scope Argumentsatz generiert Objective Sharpie keine Bindungen für Kopfzeilen außerhalb des bereichsbezogenen Ordners.

Die folgende Ausgabe wird im Terminal generiert:

Europa:Resources kmullins$ sharpie bind -output InfColorPicker -namespace InfColorPicker -sdk iphoneos8.1 /Users/kmullins/Projects/InfColorPicker/InfColorPicker/InfColorPicker.h -unified
Compiler configuration:
    -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk -miphoneos-version-min=8.1 -resource-dir /Library/Frameworks/ObjectiveSharpie.framework/Versions/1.1.1/clang-resources -arch armv7 -ObjC

[  0%] parsing /Users/kmullins/Projects/InfColorPicker/InfColorPicker/InfColorPicker.h
In file included from /Users/kmullins/Projects/InfColorPicker/InfColorPicker/InfColorPicker.h:60:
/Users/kmullins/Projects/InfColorPicker/InfColorPicker/InfColorPickerController.h:28:1: warning: no 'assign',
      'retain', or 'copy' attribute is specified - 'assign' is assumed [-Wobjc-property-no-attribute]
@property (nonatomic) UIColor* sourceColor;
^
/Users/kmullins/Projects/InfColorPicker/InfColorPicker/InfColorPickerController.h:28:1: warning: default property
      attribute 'assign' not appropriate for non-GC object [-Wobjc-property-no-attribute]
/Users/kmullins/Projects/InfColorPicker/InfColorPicker/InfColorPickerController.h:29:1: warning: no 'assign',
      'retain', or 'copy' attribute is specified - 'assign' is assumed [-Wobjc-property-no-attribute]
@property (nonatomic) UIColor* resultColor;
^
/Users/kmullins/Projects/InfColorPicker/InfColorPicker/InfColorPickerController.h:29:1: warning: default property
      attribute 'assign' not appropriate for non-GC object [-Wobjc-property-no-attribute]
4 warnings generated.
[100%] parsing complete
[bind] InfColorPicker.cs
Europa:Resources kmullins$

Und die Dateien InfColorPicker.enums.cs und InfColorPicker.cs werden in unserem Verzeichnis erstellt:

The InfColorPicker.enums.cs and InfColorPicker.cs files

Öffnen Sie beide Dateien im oben erstellten Bindungsprojekt. Kopieren Sie den Inhalt der Datei InfColorPicker.cs , und fügen Sie sie in die Datei "ApiDefinition.cs " ein, und ersetzen Sie den vorhandenen namespace ... Codeblock durch den Inhalt der Datei "InfColorPicker.cs " (die Anweisungen bleiben using erhalten):

The InfColorPickerControllerDelegate file

Normalisieren der API-Definitionen

Objective Sharpie hat manchmal ein Problem beim Übersetzen Delegates, daher müssen wir die Definition der InfColorPickerControllerDelegate Schnittstelle ändern und die [Protocol, Model] Zeile durch Folgendes ersetzen:

[BaseType(typeof(NSObject))]
[Model]

So sieht die Definition wie folgt aus:

The definition

Als Nächstes tun wir dasselbe mit dem Inhalt der InfColorPicker.enums.cs Datei, kopieren und einfügen sie in die StructsAndEnums.cs Datei, wobei die using Anweisungen intakt bleiben:

The contents the StructsAndEnums.cs file

Möglicherweise stellen Sie auch fest, dass Objective Sharpie die Bindung mit [Verify] Attributen kommentiert hat. Diese Attribute geben an, dass Sie überprüfen sollten, ob Objective Sharpie das richtige gemacht hat, indem Sie die Bindung mit der ursprünglichen C/Objective-C -Deklaration vergleichen (die in einem Kommentar oberhalb der gebundenen Deklaration angegeben wird). Nachdem Sie die Bindungen überprüft haben, sollten Sie das Verify-Attribut entfernen. Weitere Informationen finden Sie im Leitfaden "Überprüfen ".

An diesem Punkt sollte unser verbindliches Projekt fertig sein und bereit für den Bau sein. Lassen Sie uns unser Bindungsprojekt erstellen und sicherstellen, dass wir ohne Fehler beendet wurden:

Erstellen Sie das Bindungsprojekt, und stellen Sie sicher, dass keine Fehler vorhanden sind.

Verwenden der Bindung

Führen Sie die folgenden Schritte aus, um eine i Telefon-Beispielanwendung zum Verwenden der oben erstellten iOS-Bindungsbibliothek zu erstellen:

  1. Erstellen Sie Xamarin.iOS-Projekt – Fügen Sie ein neues Xamarin.iOS-Projekt namens "InfColorPickerSample " zur Lösung hinzu, wie in den folgenden Screenshots gezeigt:

    Adding a Single View App

    Setting the Identifier

  2. Hinzufügen eines Verweises auf das Bindungsprojekt – Aktualisieren Sie das Projekt InfColorPickerSample so, dass es über einen Verweis auf das InfColorPickerBinding-Projekt verfügt:

    Adding Reference to the Binding Project

  3. Erstellen Sie die i Telefon-Benutzeroberfläche – Doppelklicken Sie im InfColorPickerSample-Projekt auf die Datei "MainStoryboard.storyboard", um sie im iOS-Designer zu bearbeiten. Fügen Sie der Ansicht eine Schaltfläche hinzu, und rufen Sie sie ChangeColorButtonauf, wie in der folgenden Abbildung gezeigt:

    Adding a Button to the view

  4. Fügen Sie die InfColorPickerView.xib - Die InfColorPicker-Bibliothek Objective-C enthält eine XIB-Datei . Xamarin.iOS enthält dieses XIB nicht in das Bindungsprojekt, das Laufzeitfehler in unserer Beispielanwendung verursacht. Die Problemumgehung hierfür besteht darin, die XIB-Datei zu unserem Xamarin.iOS-Projekt hinzuzufügen. Wählen Sie das Xamarin.iOS-Projekt aus, klicken Sie mit der rechten Maustaste, und wählen Sie "Dateien hinzufügen>" aus, und fügen Sie die XIB-Datei hinzu, wie im folgenden Screenshot gezeigt:

    Add the InfColorPickerView.xib

  5. Wenn Sie gefragt werden, kopieren Sie die XIB-Datei in das Projekt.

Als Nächstes werfen wir einen schnellen Blick auf Protokolle Objective-C und deren Behandlung in Bindungs- und C#-Code.

Protokolle und Xamarin.iOS

In Objective-C, ein Protokoll definiert Methoden (oder Nachrichten), die unter bestimmten Umständen verwendet werden können. Konzeptionell sind sie den Schnittstellen in C# sehr ähnlich. Ein hauptunterschied zwischen einem Objective-C Protokoll und einer C#-Schnittstelle besteht darin, dass Protokolle optionale Methoden aufweisen können – Methoden, die eine Klasse nicht implementieren muss. Objective-Cverwendet die @optional Schlüsselwort (keyword) wird verwendet, um anzugeben, welche Methoden optional sind. Weitere Informationen zu Protokollen finden Sie unter Ereignisse, Protokolle und Stellvertretungen.

InfColorPickerController verfügt über ein solches Protokoll, das im folgenden Codeausschnitt gezeigt wird:

@protocol InfColorPickerControllerDelegate

@optional

- (void) colorPickerControllerDidFinish: (InfColorPickerController*) controller;
// This is only called when the color picker is presented modally.

- (void) colorPickerControllerDidChangeColor: (InfColorPickerController*) controller;

@end

Dieses Protokoll wird von InfColorPickerController verwendet, um Clients darüber zu informieren, dass der Benutzer eine neue Farbe ausgewählt hat und dass der InfColorPickerController abgeschlossen ist. Objective Sharpie hat dieses Protokoll wie im folgenden Codeausschnitt dargestellt zugeordnet:

[BaseType(typeof(NSObject))]
[Model]
public partial interface InfColorPickerControllerDelegate {

    [Export ("colorPickerControllerDidFinish:")]
    void ColorPickerControllerDidFinish (InfColorPickerController controller);

    [Export ("colorPickerControllerDidChangeColor:")]
    void ColorPickerControllerDidChangeColor (InfColorPickerController controller);
}

Wenn die Bindungsbibliothek kompiliert wird, erstellt Xamarin.iOS eine abstrakte Basisklasse, InfColorPickerControllerDelegatedie diese Schnittstelle mit virtuellen Methoden implementiert.

Es gibt zwei Möglichkeiten, diese Schnittstelle in einer Xamarin.iOS-Anwendung zu implementieren:

  • Starke Stellvertretung – Die Verwendung eines starken Delegaten umfasst das Erstellen einer C#-Klasse, die die entsprechenden Methoden unterordnet InfColorPickerControllerDelegate und überschreibt. InfColorPickerController verwendet eine Instanz dieser Klasse, um mit seinen Clients zu kommunizieren.
  • Schwacher Delegat – Eine schwache Stellvertretung ist eine etwas andere Technik, die das Erstellen einer öffentlichen Methode für eine Klasse (z InfColorPickerSampleViewController. B. ) und dann die Veröffentlichung dieser Methode für das InfColorPickerDelegate Protokoll über ein Export Attribut umfasst.

Starke Stellvertretungen bieten IntelliSense, Typsicherheit und bessere Kapselung. Aus diesen Gründen sollten Sie starke Stellvertretungen verwenden, wo Sie anstelle einer schwachen Stellvertretung können.

In dieser exemplarischen Vorgehensweise werden beide Techniken erörtert: zuerst eine starke Stellvertretung implementieren und dann erklären, wie eine schwache Stellvertretung implementiert wird.

Implementieren einer starken Stellvertretung

Beenden Sie die Xamarin.iOS-Anwendung, indem Sie eine starke Stellvertretung verwenden, um auf die colorPickerControllerDidFinish: Nachricht zu antworten:

Subclass InfColorPickerControllerDelegate – Fügen Sie dem Projekt eine neue Klasse hinzu, die aufgerufen wird ColorSelectedDelegate. Bearbeiten Sie die Klasse so, dass sie den folgenden Code aufweist:

using InfColorPickerBinding;
using UIKit;

namespace InfColorPickerSample
{
  public class ColorSelectedDelegate:InfColorPickerControllerDelegate
  {
    readonly UIViewController parent;

    public ColorSelectedDelegate (UIViewController parent)
    {
      this.parent = parent;
    }

    public override void ColorPickerControllerDidFinish (InfColorPickerController controller)
    {
      parent.View.BackgroundColor = controller.ResultColor;
      parent.DismissViewController (false, null);
    }
  }
}

Xamarin.iOS bindet den Objective-C Delegaten durch Erstellen einer abstrakten Basisklasse namens InfColorPickerControllerDelegate. Unterklasse dieses Typs und Überschreiben der ColorPickerControllerDidFinish Methode für den Zugriff auf den Wert der ResultColor Eigenschaft von InfColorPickerController.

Erstellen Sie eine Instanz von ColorSelectedDelegate – Unser Ereignishandler benötigt eine Instanz des Typs, den ColorSelectedDelegate wir im vorherigen Schritt erstellt haben. Bearbeiten Sie die Klasse InfColorPickerSampleViewController , und fügen Sie der Klasse die folgende Instanzvariable hinzu:

ColorSelectedDelegate selector;

Initialisieren Sie die ColorSelectedDelegate-Variable – Um sicherzustellen, dass es selector sich um eine gültige Instanz handelt, aktualisieren Sie die Methode ViewDidLoadViewController so, dass sie mit dem folgenden Codeausschnitt übereinstimmt:

public override void ViewDidLoad ()
{
  base.ViewDidLoad ();
  ChangeColorButton.TouchUpInside += HandleTouchUpInsideWithStrongDelegate;
  selector = new ColorSelectedDelegate (this);
}

Implementieren Sie die Methode HandleTouchUpInsideWithStrongDelegate – Implementieren Sie als Nächstes den Ereignishandler, wenn der Benutzer ColorChangeButton berührt. Bearbeiten sie ViewController, und fügen Sie die folgende Methode hinzu:

using InfColorPicker;
...

private void HandleTouchUpInsideWithStrongDelegate (object sender, EventArgs e)
{
    InfColorPickerController picker = InfColorPickerController.ColorPickerViewController();
    picker.Delegate = selector;
    picker.PresentModallyOverViewController (this);
}

Wir rufen zunächst eine Instanz InfColorPickerController einer statischen Methode ab und machen diese Instanz über die Eigenschaft InfColorPickerController.Delegateauf unseren starken Delegaten aufmerksam. Diese Eigenschaft wurde automatisch von Objective Sharpie für uns generiert. Schließlich rufen PresentModallyOverViewController wir auf, die Ansicht InfColorPickerSampleViewController.xib anzuzeigen, damit der Benutzer eine Farbe auswählen kann.

Führen Sie die Anwendung aus– An diesem Punkt sind wir mit dem gesamten Code fertig. Wenn Sie die Anwendung ausführen, sollten Sie in der Lage sein, die Hintergrundfarbe der InfColorColorPickerSampleView in den folgenden Screenshots gezeigten Zu ändern:

Running the Application

Herzlichen Glückwunsch! An diesem Punkt haben Sie erfolgreich eine Objective-C Bibliothek für die Verwendung in einer Xamarin.iOS-Anwendung erstellt und gebunden. Als Nächstes lernen wir die Verwendung schwacher Stellvertretungen kennen.

Implementieren einer schwachen Stellvertretung

Anstatt eine Klasse zu unterklassen, die an das Objective-C Protokoll für einen bestimmten Delegaten gebunden ist, können Sie mit Xamarin.iOS auch die Protokollmethoden in jeder Klasse implementieren, von NSObjectder abgeleitet wird, die Methoden mit dem ExportAttributeProtokoll versehen und dann die entsprechenden Selektoren bereitstellen. Wenn Sie diesen Ansatz verwenden, weisen Sie der WeakDelegate Eigenschaft anstelle der Delegate Eigenschaft eine Instanz Ihrer Klasse zu. Eine schwache Stellvertretung bietet Ihnen die Flexibilität, Ihre Stellvertretungsklasse in eine andere Vererbungshierarchie zu übernehmen. Sehen wir uns an, wie sie eine schwache Stellvertretung in unserer Xamarin.iOS-Anwendung implementieren und verwenden.

Create Event Handler for TouchUpInside - Let's create a new event handler for the TouchUpInside event of the Change Background Color button. Dieser Handler füllt dieselbe Rolle wie der Handler aus, den HandleTouchUpInsideWithStrongDelegate wir im vorherigen Abschnitt erstellt haben, verwendet aber einen schwachen Delegaten anstelle eines starken Delegaten. Bearbeiten Sie die Klasse ViewController, und fügen Sie die folgende Methode hinzu:

private void HandleTouchUpInsideWithWeakDelegate (object sender, EventArgs e)
{
    InfColorPickerController picker = InfColorPickerController.ColorPickerViewController();
    picker.WeakDelegate = this;
    picker.SourceColor = this.View.BackgroundColor;
    picker.PresentModallyOverViewController (this);
}

ViewDidLoad aktualisieren – Wir müssen so ändern ViewDidLoad , dass er den soeben erstellten Ereignishandler verwendet. Bearbeiten und ändern ViewDidLoad Sie ViewController den folgenden Codeausschnitt:

public override void ViewDidLoad ()
{
    base.ViewDidLoad ();
    ChangeColorButton.TouchUpInside += HandleTouchUpInsideWithWeakDelegate;
}

Handle the colorPickerControllerDidFinish: Message - When the ViewController finished, iOS will send the message colorPickerControllerDidFinish: to the WeakDelegate. Wir müssen eine C#-Methode erstellen, die diese Nachricht verarbeiten kann. Dazu erstellen wir eine C#-Methode und schmücken sie dann mit der ExportAttribute. Bearbeiten Sie ViewControllerdie Klasse, und fügen Sie der Klasse die folgende Methode hinzu:

[Export("colorPickerControllerDidFinish:")]
public void ColorPickerControllerDidFinish (InfColorPickerController controller)
{
    View.BackgroundColor = controller.ResultColor;
    DismissViewController (false, null);
}

Führen Sie die Anwendung aus. Es sollte sich jetzt genau so verhalten wie zuvor, aber es verwendet eine schwache Stellvertretung anstelle der starken Stellvertretung. An diesem Punkt haben Sie diese exemplarische Vorgehensweise erfolgreich abgeschlossen. Sie sollten nun wissen, wie Sie ein Xamarin.iOS-Bindungsprojekt erstellen und nutzen können.

Zusammenfassung

In diesem Artikel wurde das Erstellen und Verwenden eines Xamarin.iOS-Bindungsprojekts erläutert. Zunächst wurde erläutert, wie eine vorhandene Objective-C Bibliothek in eine statische Bibliothek kompiliert wird. Anschließend wurde erläutert, wie Sie ein Xamarin.iOS-Bindungsprojekt erstellen und wie Objective Sharpie zum Generieren der API-Definitionen für die Objective-C Bibliothek verwendet wird. Wir haben erläutert, wie die generierten API-Definitionen aktualisiert und optimiert werden, um sie für den öffentlichen Gebrauch geeignet zu machen. Nachdem das Xamarin.iOS-Bindungsprojekt abgeschlossen wurde, haben wir uns dazu bewegt, diese Bindung in einer Xamarin.iOS-Anwendung zu verwenden, wobei der Fokus auf der Verwendung starker Stellvertretungen und schwacher Stellvertretungen liegt.