Udostępnij za pośrednictwem


Przewodnik: wiązanie biblioteki systemu iOS Objective-C

Ważne

Obecnie badamy użycie powiązań niestandardowych na platformie Xamarin. Weź udział w tej ankiecie , aby poinformować o przyszłych wysiłkach programistycznych.

Ten artykuł zawiera praktyczny przewodnik tworzenia powiązania platformy Xamarin.iOS dla istniejącej Objective-C biblioteki InfColorPicker. Obejmuje on tematy, takie jak kompilowanie biblioteki statycznej Objective-C , wiązanie jej i używanie powiązania w aplikacji platformy Xamarin.iOS.

Podczas pracy z systemem iOS mogą wystąpić przypadki, w których chcesz korzystać z biblioteki innej firmy Objective-C . W takich sytuacjach można użyć projektu powiązania platformy Xamarin.iOS, aby utworzyć powiązanie języka C#, które umożliwi korzystanie z biblioteki w aplikacjach platformy Xamarin.iOS.

Ogólnie w ekosystemie systemu iOS biblioteki można znaleźć w 3 odmianach:

  • Jako wstępnie skompilowany plik biblioteki statycznej z .a rozszerzeniem wraz z nagłówkami (plikami h). Na przykład biblioteka usługi Google Analytics
  • Jako wstępnie skompilowana struktura. Jest to tylko folder zawierający bibliotekę statyczną, nagłówki i czasami dodatkowe zasoby z .framework rozszerzeniem. Na przykład biblioteka AdMob firmy Google.
  • Podobnie jak pliki kodu źródłowego. Na przykład biblioteka zawierająca tylko .m pliki Objective C..h

W pierwszym i drugim scenariuszu będzie już wstępnie skompilowana biblioteka statyczna CocoaTouch, więc w tym artykule skupimy się na trzecim scenariuszu. Pamiętaj, że przed rozpoczęciem tworzenia powiązania należy zawsze sprawdzić licencję dostarczoną z biblioteką, aby upewnić się, że jest ona bezpłatna.

Ten artykuł zawiera szczegółowy przewodnik tworzenia projektu powiązania przy użyciu projektu InfColorPicker typu open source, jednak wszystkie informacje zawarte w tym przewodniku można dostosować do użycia z dowolną biblioteką innej firmyObjective-C.Objective-C Biblioteka InfColorPicker udostępnia kontroler widoku wielokrotnego użytku, który umożliwia użytkownikowi wybranie koloru na podstawie jego reprezentacji HSB, dzięki czemu wybór kolorów jest bardziej przyjazny dla użytkownika.

Example of the InfColorPicker library running on iOS

Omówimy wszystkie kroki niezbędne do korzystania z tego konkretnego Objective-C interfejsu API na platformie Xamarin.iOS:

  • Najpierw utworzymy bibliotekę statyczną Objective-C przy użyciu środowiska Xcode.
  • Następnie powiążemy tę bibliotekę statyczną z platformą Xamarin.iOS.
  • Następnie pokaż, jak narzędzie Objective Sharpie może zmniejszyć obciążenie, automatycznie generując niektóre (ale nie wszystkie) niezbędne definicje interfejsu API wymagane przez powiązanie platformy Xamarin.iOS.
  • Na koniec utworzymy aplikację platformy Xamarin.iOS, która używa powiązania.

Przykładowa aplikacja pokaże, jak używać silnego delegata do komunikacji między interfejsem API InfColorPicker i naszym kodem języka C#. Po tym, jak użyć silnego delegata, omówimy sposób używania słabych delegatów do wykonywania tych samych zadań.

Wymagania

W tym artykule założono, że masz pewną znajomość języka Xcode i Objective-C języka, a ty zapoznasz się z naszą dokumentacją powiązania Objective-C . Ponadto do wykonania przedstawionych kroków są wymagane następujące czynności:

  • Zestaw SDK Xcode i iOS — środowisko Xcode firmy Apple i najnowszy interfejs API systemu iOS muszą być zainstalowane i skonfigurowane na komputerze dewelopera.
  • Narzędzia wiersza polecenia Xcode — narzędzia wiersza polecenia programu Xcode muszą być zainstalowane dla aktualnie zainstalowanej wersji programu Xcode (zobacz poniżej, aby uzyskać szczegółowe informacje o instalacji).
  • Visual Studio dla komputerów Mac lub Visual Studio — najnowsza wersja Visual Studio dla komputerów Mac lub Visual Studio powinna być zainstalowana i skonfigurowana na komputerze dewelopera. Komputer Mac firmy Apple jest wymagany do tworzenia aplikacji platformy Xamarin.iOS, a w przypadku korzystania z programu Visual Studio musisz mieć połączenie z hostem kompilacji platformy Xamarin.iOS
  • Najnowsza wersja aplikacji Objective Sharpie — bieżąca kopia narzędzia Objective Sharpie pobranego tutaj. Jeśli masz już zainstalowany program Objective Sharpie, możesz zaktualizować go do najnowszej wersji przy użyciu narzędzia sharpie update

Instalowanie narzędzi wiersza polecenia programu Xcode

Jak wspomniano powyżej, będziemy używać narzędzi wiersza polecenia Xcode (w szczególności make i lipo) w tym przewodniku. Polecenie make jest bardzo popularnym narzędziem systemu Unix, które automatyzuje kompilację programów wykonywalnych i bibliotek przy użyciu pliku make, który określa sposób tworzenia programu. Polecenie lipo jest narzędziem wiersza polecenia systemu OS X do tworzenia plików z wieloma architekturami. Połączy wiele .a plików w jeden plik, który może być używany przez wszystkie architektury sprzętowe.

Zgodnie z dokumentacją kompilowania firmy Apple z poziomu wiersza polecenia za pomocą narzędzia Xcode FAQ w systemie OS X 10.9 i nowszym okienko Pobieranie okna dialogowego Preferencje programu Xcode nie obsługuje już narzędzi wiersza polecenia do pobierania.

Aby zainstalować narzędzia, należy użyć jednej z następujących metod:

  • Zainstaluj program Xcode — podczas instalowania programu Xcode jest on dostarczany wraz ze wszystkimi narzędziami wiersza polecenia. W podkładkach systemu OS X 10.9 (zainstalowanym w systemie /usr/bin), można mapować dowolne narzędzie dołączone /usr/bin do odpowiedniego narzędzia wewnątrz programu Xcode. Na przykład xcrun polecenie, które umożliwia znalezienie lub uruchomienie dowolnego narzędzia w środowisku Xcode z poziomu wiersza polecenia.

  • Aplikacja terminalowa — z poziomu aplikacji terminalowej możesz zainstalować narzędzia wiersza polecenia, uruchamiając xcode-select --install polecenie:

    • Uruchom aplikację terminalu.
    • Wpisz xcode-select --install i naciśnij klawisz Enter, na przykład:
    Europa:~ kmullins$ xcode-select --install
    
    • Zostanie wyświetlony monit o zainstalowanie narzędzi wiersza polecenia, kliknij przycisk Zainstaluj : Installing the command line tools

    • Narzędzia zostaną pobrane i zainstalowane z serwerów firmy Apple: Downloading the tools

  • Pliki do pobrania dla deweloperów firmy Apple — pakiet Narzędzi wiersza polecenia jest dostępny na stronie internetowej Pliki do pobrania dla deweloperów firmy Apple. Zaloguj się przy użyciu identyfikatora Apple ID, a następnie wyszukaj i pobierz narzędzia wiersza polecenia: Finding the Command Line Tools

Po zainstalowaniu narzędzi wiersza polecenia możemy kontynuować pracę z przewodnikiem.

Przewodnik

W tym przewodniku omówimy następujące kroki:

  • Tworzenie biblioteki statycznej — ten krok obejmuje utworzenie biblioteki statycznej kodu InfColorPickerObjective-C. Biblioteka statyczna będzie mieć .a rozszerzenie pliku i zostanie osadzona w zestawie .NET projektu biblioteki.
  • Tworzenie projektu powiązania platformy Xamarin.iOS — po utworzeniu biblioteki statycznej użyjemy go do utworzenia projektu powiązania platformy Xamarin.iOS. Projekt powiązania składa się z właśnie utworzonej biblioteki statycznej i metadanych w postaci kodu języka C#, który wyjaśnia, jak można używać interfejsu Objective-C API. Te metadane są często określane jako definicje interfejsu API. Użyjemy języka Objective Sharpie , aby pomóc nam w tworzeniu definicji interfejsu API.
  • Normalizacja definicji interfejsu API — Objective Sharpie doskonale pomaga nam, ale nie może wykonywać wszystkiego. Omówimy pewne zmiany, które należy wprowadzić w definicjach interfejsu API, zanim będą mogły być używane.
  • Użyj biblioteki powiązań — na koniec utworzymy aplikację platformy Xamarin.iOS, aby pokazać, jak używać nowo utworzonego projektu powiązania.

Teraz, gdy zrozumiemy, jakie kroki są zaangażowane, przejdźmy do pozostałej części przewodnika.

Tworzenie biblioteki statycznej

Jeśli sprawdzimy kod dla platformy InfColorPicker w usłudze Github:

Inspect the code for InfColorPicker in Github

W projekcie są widoczne następujące trzy katalogi:

  • InfColorPicker — ten katalog zawiera Objective-C kod projektu.
  • PickerSamplePad — ten katalog zawiera przykładowy projekt tabletu iPad.
  • PickerSample Telefon — ten katalog zawiera przykładowy projekt i Telefon.

Pobierzmy projekt InfColorPicker z usługi GitHub i rozpakujmy go w wybranym katalogu. Otwarcie obiektu docelowego programu Xcode dla PickerSamplePhone projektu jest widoczna następująca struktura projektu w nawigatorze Xcode:

The project structure in the Xcode Navigator

Ten projekt umożliwia ponowne użycie kodu przez bezpośrednie dodanie kodu źródłowego InfColorPicker (w czerwonym polu) do każdego przykładowego projektu. Kod przykładowego projektu znajduje się wewnątrz niebieskiego pola. Ponieważ ten konkretny projekt nie udostępnia nam biblioteki statycznej, konieczne jest utworzenie projektu Xcode w celu skompilowania biblioteki statycznej.

Pierwszym krokiem jest dodanie kodu źródłowego InfoColorPicker do biblioteki statycznej. Aby to osiągnąć, wykonajmy następujące czynności:

  1. Uruchom program Xcode.

  2. W menu Plik wybierz pozycję Nowy>projekt...:

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

  3. Wybierz pozycję Struktura i biblioteka, szablon Biblioteki statycznej Cocoa Touch i kliknij przycisk Dalej :

    Select the Cocoa Touch Static Library template

  4. Wprowadź InfColorPicker nazwę projektu i kliknij przycisk Dalej:

    Enter InfColorPicker for the Project Name

  5. Wybierz lokalizację do zapisania projektu i kliknij przycisk OK .

  6. Teraz musimy dodać źródło z projektu InfColorPicker do projektu biblioteki statycznej. Ponieważ plik InfColorPicker.h już istnieje w naszej bibliotece statycznej (domyślnie), program Xcode nie pozwoli nam go zastąpić. W narzędziu Finder przejdź do kodu źródłowego InfColorPicker w oryginalnym projekcie, który rozpakowaliśmy z usługi GitHub, skopiuj wszystkie pliki InfColorPicker i wklej je do naszego nowego projektu biblioteki statycznej:

    Copy all of the InfColorPicker files

  7. Wróć do programu Xcode, kliknij prawym przyciskiem myszy folder InfColorPicker i wybierz polecenie Dodaj pliki do pozycji "InfColorPicker...":

    Adding files

  8. W oknie dialogowym Dodawanie plików przejdź do skopiowanych plików kodu źródłowego InfColorPicker, zaznacz je wszystkie i kliknij przycisk Dodaj :

    Select all and click the Add button

  9. Kod źródłowy zostanie skopiowany do naszego projektu:

    The source code will be copied into the project

  10. W nawigatorze projektu Xcode wybierz plik InfColorPicker.m i oznacz jako komentarz ostatnie dwa wiersze (ze względu na sposób, w jaki ta biblioteka została napisana, ten plik nie jest używany):

    Editing the InfColorPicker.m file

  11. Teraz musimy sprawdzić, czy istnieją jakiekolwiek struktury wymagane przez bibliotekę. Te informacje można znaleźć w pliku README lub otwierając jeden z udostępnionych przykładowych projektów. W tym przykładzie użyto Foundation.frameworkwartości , UIKit.frameworki CoreGraphics.framework dlatego dodajmy je.

  12. Wybierz docelowe > fazy kompilacji infColorPicker i rozwiń sekcję Połącz plik binarny z bibliotekami:

    Expand the Link Binary With Libraries section

  13. + Użyj przycisku , aby otworzyć okno dialogowe umożliwiające dodanie wymaganych struktur ramek wymienionych powyżej:

    Add the required frames frameworks listed above

  14. Sekcja Link binarny z bibliotekami powinna teraz wyglądać podobnie do poniższego obrazu:

    The Link Binary With Libraries section

W tym momencie jesteśmy blisko, ale nie jesteśmy do końca. Utworzono bibliotekę statyczną, ale musimy ją skompilować, aby utworzyć plik binarny Fat zawierający wszystkie wymagane architektury zarówno dla urządzenia z systemem iOS, jak i symulatora systemu iOS.

Tworzenie pliku binarnego tłuszczu

Wszystkie urządzenia z systemem iOS mają procesory obsługiwane przez architekturę ARM, które zostały opracowane w czasie. Każda nowa architektura dodała nowe instrukcje i inne ulepszenia przy zachowaniu zgodności z poprzednimi wersjami. Urządzenia z systemem iOS mają armv6, armv7, armv7s, arm64 zestawy instrukcji — chociaż armv6 nie były już używane. Symulator systemu iOS nie jest obsługiwany przez usługę ARM i jest zamiast niego symulatorem opartym na architekturze x86 i x86_64. Oznacza to, że biblioteki muszą być udostępniane dla każdego zestawu instrukcji.

Biblioteka fat jest .a plikiem zawierającym wszystkie obsługiwane architektury.

Tworzenie pliku binarnego tłuszczu jest procesem trzyetapowym:

  • Skompiluj wersję biblioteki statycznej ARM 7 i ARM64.
  • Skompiluj wersję biblioteki statycznej x86 i x84_64.
  • lipo Użyj narzędzia wiersza polecenia, aby połączyć dwie biblioteki statyczne w jeden.

Chociaż te trzy kroki są dość proste, może być konieczne ich powtórzenie w przyszłości, gdy Objective-C biblioteka odbiera aktualizacje lub jeśli wymagamy poprawek błędów. Jeśli zdecydujesz się zautomatyzować te kroki, uprości to przyszłą konserwację i obsługę projektu powiązania systemu iOS.

Dostępnych jest wiele narzędzi do automatyzowania takich zadań — skrypt powłoki, rake, xbuild i make. Po zainstalowaniu make narzędzi wiersza polecenia programu Xcode jest również zainstalowany system kompilacji, który będzie używany w tym przewodniku. Oto plik programu Make, którego można użyć do utworzenia biblioteki udostępnionej z wieloma architekturami, która będzie działać na urządzeniu z systemem iOS i symulatorze dowolnej biblioteki:

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

Wprowadź polecenia programu Makefile w wybranym edytorze zwykłego tekstu i zaktualizuj sekcje przy użyciu nazwy YOUR-PROJECT-NAME z nazwą projektu. Ważne jest również, aby upewnić się, że wklejasz powyższe instrukcje dokładnie, z kartami w instrukcjach zachowanych.

Zapisz plik o nazwie Makefile w tej samej lokalizacji co utworzona powyżej biblioteka statyczna InfColorPicker Xcode:

Save the file with the name Makefile

Otwórz aplikację terminalu na komputerze Mac i przejdź do lokalizacji pliku programu Make. Wpisz make w terminalu, naciśnij klawisz Enter , a plik Make zostanie wykonany:

Sample makefile output

Po uruchomieniu polecenia zostanie wyświetlonych wiele przewijania tekstu. Jeśli wszystko działa poprawnie, zobaczysz wyrazy BUILD SUCCEEDED (KOMPILACJA POWIODŁA się ) i libInfColorPicker-armv7.apliki , libInfColorPicker-i386.a a libInfColorPickerSDK.a pliki zostaną skopiowane do tej samej lokalizacji co plik programu Make:

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

Architektury w pliku binarnym Fat można potwierdzić za pomocą następującego polecenia:

xcrun -sdk iphoneos lipo -info libInfColorPicker.a

Powinno to wyświetlić następujące elementy:

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

Na tym etapie wykonaliśmy pierwszy krok powiązania systemu iOS, tworząc bibliotekę statyczną przy użyciu środowiska Xcode i narzędzi make wiersza polecenia Xcode i lipo. Przejdźmy do następnego kroku i użyjemy języka Objective-Sharpie , aby zautomatyzować tworzenie powiązań interfejsu API dla nas.

Tworzenie projektu powiązania platformy Xamarin.iOS

Zanim będziemy mogli zautomatyzować proces wiązania za pomocą języka Objective-Sharpie , musimy utworzyć projekt powiązania platformy Xamarin.iOS, aby pomieścić definicje interfejsu API (które będą używane w narzędziu Objective-Sharpie , aby pomóc nam skompilować) i utworzyć powiązanie języka C#.

Wykonajmy następujące czynności:

  1. Uruchom Visual Studio dla komputerów Mac.

  2. W menu Plik wybierz pozycję Nowe>rozwiązanie...:

    Starting a new solution

  3. W oknie dialogowym Nowe rozwiązanie wybierz pozycję Biblioteka>projektu powiązania systemu iOS:

    Select iOS Binding Project

  4. Kliknij przycisk Next (Dalej).

  5. Wprowadź ciąg "InfColorPickerBinding" jako nazwę projektu i kliknij przycisk Utwórz , aby utworzyć rozwiązanie:

    Enter InfColorPickerBinding as the Project Name

Rozwiązanie zostanie utworzone i zostaną dołączone dwa pliki domyślne:

The solution structure in the Solution Explorer

  • ApiDefinition.cs — ten plik będzie zawierać kontrakty definiujące sposób Objective-C opakowania interfejsu API w języku C#.
  • Structs.cs — ten plik będzie przechowywać wszystkie struktury lub wartości wyliczenia wymagane przez interfejsy i delegaty.

Będziemy pracować z tymi dwoma plikami w dalszej części przewodnika. Najpierw musimy dodać bibliotekę InfColorPicker do projektu powiązania.

Dołączanie biblioteki statycznej w projekcie powiązania

Teraz mamy gotowy podstawowy projekt powiązania, musimy dodać bibliotekę Fat Binary utworzoną powyżej dla biblioteki InfColorPicker .

Wykonaj następujące kroki, aby dodać bibliotekę:

  1. Kliknij prawym przyciskiem myszy folder Native References (Odwołania natywne) w okienku rozwiązania i wybierz polecenie Dodaj odwołania natywne:

    Add Native References

  2. Przejdź do pliku Fat Binary utworzonego wcześniej (libInfColorPickerSDK.a) i naciśnij przycisk Otwórz :

    Select the libInfColorPickerSDK.a file

  3. Plik zostanie uwzględniony w projekcie:

    Including a file

Po dodaniu pliku do projektu program Xamarin.iOS automatycznie ustawi akcję kompilacji pliku na ObjcBindingNativeLibrary i utworzy specjalny plik o nazwie libInfColorPickerSDK.linkwith.cs.

Ten plik zawiera LinkWith atrybut, który informuje platformę Xamarin.iOS, jak obsługuje właśnie dodaną bibliotekę statyczną. Zawartość tego pliku jest wyświetlana w następującym fragmencie kodu:

using ObjCRuntime;

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

Atrybut LinkWith identyfikuje bibliotekę statyczną dla projektu i niektóre ważne flagi konsolidatora.

Następną czynnością, którą musimy zrobić, jest utworzenie definicji interfejsu API dla projektu InfColorPicker. Na potrzeby tego przewodnika użyjemy narzędzia Objective Sharpie do wygenerowania ApiDefinition.cs pliku.

Korzystanie z aplikacji Objective Sharpie

Objective Sharpie to narzędzie wiersza polecenia (udostępniane przez platformę Xamarin), które może pomóc w tworzeniu definicji wymaganych do powiązania biblioteki innej firmy Objective-C z C#. W tej sekcji użyjemy narzędzia Objective Sharpie do utworzenia początkowej ApiDefinition.cs dla projektu InfColorPicker.

Aby rozpocząć, pobierzmy plik instalatora Objective Sharpie zgodnie z opisem w tym przewodniku. Uruchom instalatora i postępuj zgodnie ze wszystkimi monitami wyświetlanymi na ekranie kreatora instalacji, aby zainstalować aplikację Objective Sharpie na naszym komputerze deweloperów.

Po pomyślnym zainstalowaniu aplikacji Objective Sharpie uruchomimy aplikację terminalu i wprowadźmy następujące polecenie, aby uzyskać pomoc dotyczącą wszystkich narzędzi, które udostępnia, aby pomóc w powiązaniu:

sharpie -help

Jeśli wykonamy powyższe polecenie, zostaną wygenerowane następujące dane wyjściowe:

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

W tym przewodniku użyjemy następujących narzędzi Objective Sharpie:

  • xcode — te narzędzia zawierają informacje o naszej bieżącej instalacji programu Xcode oraz wersjach zainstalowanych interfejsów API systemu iOS i Mac. Będziemy używać tych informacji później podczas generowania powiązań.
  • bind — użyjemy tego narzędzia, aby przeanalizować pliki .h w projekcie InfColorPicker do początkowych plików ApiDefinition.cs i StructsAndEnums.cs .

Aby uzyskać pomoc dotyczącą określonego narzędzia Objective Sharpie, wprowadź nazwę narzędzia i -help opcję. Na przykład sharpie xcode -help zwraca następujące dane wyjściowe:

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.

Zanim zaczniemy proces tworzenia powiązania, musimy uzyskać informacje o naszych bieżących zainstalowanych zestawach SDK, wprowadzając następujące polecenie w terminalu sharpie xcode -sdks:

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

Z powyższego wynika, że na iphoneos9.3 naszej maszynie jest zainstalowany zestaw SDK. Dzięki tym informacjom możemy przeanalizować pliki projektu .h InfColorPicker w początkowym ApiDefinition.cs i StructsAndEnums.cs w projekcie InfColorPicker.

Wprowadź następujące polecenie w aplikacji terminalu:

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

Gdzie [full-path-to-project] jest pełna ścieżka do katalogu, w którym znajduje się plik projektu InfColorPicker Xcode na naszym komputerze, a [iphone-os] jest zainstalowanym zestawem SDK systemu iOS, jak wspomniano za sharpie xcode -sdks pomocą polecenia . Należy pamiętać, że w tym przykładzie przekazano plik *.h jako parametr, który zawiera wszystkie pliki nagłówkowe w tym katalogu — zwykle nie należy tego robić, ale zamiast tego uważnie odczytywać pliki nagłówków, aby znaleźć plik .h najwyższego poziomu, który odwołuje się do wszystkich innych odpowiednich plików, i po prostu przekazać go do objective Sharpie.

Napiwek

W przypadku argumentu -scope przekaż folder zawierający nagłówki, które chcesz powiązać. Bez argumentu -scope objective Sharpie spróbuje wygenerować powiązania dla wszystkich importowanych nagłówków zestawu SDK systemu iOS, np. #import <UIKit.h>, co spowoduje utworzenie ogromnego pliku definicji, który prawdopodobnie będzie generować błędy podczas kompilowania projektu powiązania. W przypadku -scope zestawu argumentów funkcja Objective Sharpie nie będzie generować powiązań dla żadnych nagłówków poza folderem o określonym zakresie.

Następujące dane wyjściowe zostaną wygenerowane w terminalu:

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$

A pliki InfColorPicker.enums.cs i InfColorPicker.cs zostaną utworzone w naszym katalogu:

The InfColorPicker.enums.cs and InfColorPicker.cs files

Otwórz oba te pliki w projekcie Binding utworzonym powyżej. Skopiuj zawartość pliku InfColorPicker.cs i wklej go do pliku ApiDefinition.cs , zastępując istniejący namespace ... blok kodu zawartością pliku InfColorPicker.cs (pozostawiając using instrukcje nienaruszone):

The InfColorPickerControllerDelegate file

Normalizacja definicji interfejsu API

Funkcja Objective Sharpie czasami ma problem z tłumaczeniem Delegates, dlatego musimy zmodyfikować definicję interfejsu InfColorPickerControllerDelegate i zastąpić [Protocol, Model] wiersz następującymi elementami:

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

Aby definicja wyglądała następująco:

The definition

Następnie robimy to samo z zawartością InfColorPicker.enums.cs pliku, kopiując i wklejając using je w StructsAndEnums.cs pliku, pozostawiając instrukcje nienaruszone:

The contents the StructsAndEnums.cs file

Możesz również zauważyć, że element Objective Sharpie oznaczył powiązanie za pomocą [Verify] atrybutów. Te atrybuty wskazują, że należy sprawdzić, czy objective Sharpie zrobił prawidłową rzecz, porównując powiązanie z oryginalną deklaracją C/Objective-C (która zostanie podana w komentarzu powyżej deklaracji powiązanej). Po zweryfikowaniu powiązań należy usunąć atrybut verify. Aby uzyskać więcej informacji, zapoznaj się z przewodnikiem Weryfikowanie .

W tym momencie nasz projekt powiązania powinien zostać ukończony i gotowy do kompilacji. Skompilujmy nasz projekt powiązania i upewnijmy się, że nie wystąpiły żadne błędy:

Skompiluj projekt powiązania i upewnij się, że nie ma żadnych błędów

Korzystanie z powiązania

Wykonaj następujące kroki, aby utworzyć przykładową aplikację i Telefon aby użyć biblioteki powiązań systemu iOS utworzonej powyżej:

  1. Tworzenie projektu platformy Xamarin.iOS — dodaj nowy projekt platformy Xamarin.iOS o nazwie InfColorPickerSample do rozwiązania, jak pokazano na poniższych zrzutach ekranu:

    Adding a Single View App

    Setting the Identifier

  2. Dodaj odwołanie do projektu powiązania — zaktualizuj projekt InfColorPickerSample , aby miał odwołanie do projektu InfColorPickerBinding :

    Adding Reference to the Binding Project

  3. Utwórz interfejs użytkownika i Telefon — kliknij dwukrotnie plik MainStoryboard.storyboard w projekcie InfColorPickerSample, aby go edytować w Projektant systemu iOS. Dodaj przycisk do widoku i wywołaj go ChangeColorButton, jak pokazano poniżej:

    Adding a Button to the view

  4. Dodaj bibliotekę InfColorPickerView.xib — biblioteka InfColorPicker Objective-C zawiera plik xib . Środowisko Xamarin.iOS nie będzie zawierać tego pliku .xib w projekcie powiązania, co spowoduje błędy czasu wykonywania w naszej przykładowej aplikacji. Obejściem tego problemu jest dodanie pliku xib do projektu Xamarin.iOS. Wybierz projekt Xamarin.iOS, kliknij prawym przyciskiem myszy i wybierz polecenie Dodaj > pliki, a następnie dodaj plik xib , jak pokazano na poniższym zrzucie ekranu:

    Add the InfColorPickerView.xib

  5. Po wyświetleniu monitu skopiuj plik .xib do projektu.

Następnie przyjrzyjmy się szybko protokołom i Objective-C sposobie ich obsługi w powiązaniu i kodzie języka C#.

Protokoły i Xamarin.iOS

W Objective-Csystemie protokół definiuje metody (lub komunikaty), które mogą być używane w określonych okolicznościach. Koncepcyjnie są one bardzo podobne do interfejsów w języku C#. Jedną z głównych różnic między protokołem a interfejsem Objective-C języka C# jest to, że protokoły mogą mieć opcjonalne metody — metody, których klasa nie musi implementować. Objective-C używa słowa kluczowego @optional , aby wskazać, które metody są opcjonalne. Aby uzyskać więcej informacji na temat protokołów, zobacz Zdarzenia, protokoły i delegaty.

Element InfColorPickerController ma jeden taki protokół, jak pokazano w poniższym fragmencie kodu:

@protocol InfColorPickerControllerDelegate

@optional

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

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

@end

Ten protokół jest używany przez infColorPickerController , aby poinformować klientów, że użytkownik wybrał nowy kolor i że infColorPickerController jest gotowy. Objective Sharpie zamapował ten protokół, jak pokazano w poniższym fragmencie kodu:

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

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

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

Po skompilowaniu biblioteki powiązań platforma Xamarin.iOS utworzy abstrakcyjną klasę bazową o nazwie InfColorPickerControllerDelegate, która implementuje ten interfejs za pomocą metod wirtualnych.

Istnieją dwa sposoby implementacji tego interfejsu w aplikacji platformy Xamarin.iOS:

  • Strong Delegate — używanie silnego delegata polega na utworzeniu klasy języka C#, która tworzy podklasy InfColorPickerControllerDelegate i zastępuje odpowiednie metody. InfColorPickerController użyje wystąpienia tej klasy do komunikowania się z klientami.
  • Weak Delegate — słaby delegat jest nieco inną techniką, która polega na utworzeniu metody publicznej w niektórych klasach (takich jak InfColorPickerSampleViewController), a następnie uwidacznianiu tej metody w InfColorPickerDelegate protokole za pośrednictwem atrybutu Export .

Silne delegaty zapewniają funkcję IntelliSense, bezpieczeństwo typów i lepszą hermetyzację. Z tych powodów należy używać silnych delegatów, w których można, zamiast słabego delegata.

W tym przewodniku omówimy obie techniki: najpierw zaimplementowanie silnego delegata, a następnie wyjaśnienie, jak zaimplementować słabego delegata.

Implementowanie silnego delegata

Zakończ aplikację platformy Xamarin.iOS przy użyciu silnego delegata colorPickerControllerDidFinish: , aby odpowiedzieć na komunikat:

Podklasa InfColorPickerControllerDelegate — dodaj nową klasę do projektu o nazwie ColorSelectedDelegate. Zmodyfikuj klasę, aby zawierała następujący kod:

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);
    }
  }
}

Rozszerzenie Xamarin.iOS powiąże delegata Objective-C , tworząc abstrakcyjną klasę bazową o nazwie InfColorPickerControllerDelegate. Podklasa tego typu i przesłania metodę ColorPickerControllerDidFinish w celu uzyskania dostępu do wartości ResultColor właściwości InfColorPickerController.

Utwórz wystąpienie elementu ColorSelectedDelegate — nasza procedura obsługi zdarzeń będzie potrzebować wystąpienia ColorSelectedDelegate typu utworzonego w poprzednim kroku. Edytuj klasę InfColorPickerSampleViewController i dodaj następującą zmienną wystąpienia do klasy:

ColorSelectedDelegate selector;

Zainicjuj zmienną ColorSelectedDelegate — aby upewnić się, że selector jest to prawidłowe wystąpienie, zaktualizuj metodę ViewDidLoad w pliku , ViewController aby dopasować następujący fragment kodu:

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

Zaimplementuj metodę HandleTouchUpInsideWithStrongDelegate — następnie zaimplementuj procedurę obsługi zdarzeń, gdy użytkownik dotyka elementu ColorChangeButton. Zmodyfikuj ViewControllermetodę i dodaj następującą metodę:

using InfColorPicker;
...

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

Najpierw uzyskujemy wystąpienie InfColorPickerController metody statycznej i uświadomimy naszemu silnemu delegatowi za pośrednictwem właściwości InfColorPickerController.Delegate. Ta właściwość została wygenerowana automatycznie przez Objective Sharpie. Na koniec wywołujemy PresentModallyOverViewController polecenie , aby wyświetlić widok InfColorPickerSampleViewController.xib , aby użytkownik mógł wybrać kolor.

Uruchom aplikację — na tym etapie skończymy z całym naszym kodem. Jeśli uruchomisz aplikację, musisz mieć możliwość zmiany koloru tła elementu , InfColorColorPickerSampleView jak pokazano na poniższych zrzutach ekranu:

Running the Application

Gratulacje! Na tym etapie pomyślnie utworzono i powiązaliśmy bibliotekę Objective-C do użycia w aplikacji platformy Xamarin.iOS. Następnie dowiemy się, jak używać słabych delegatów.

Implementowanie słabego delegata

Zamiast podklasować klasę powiązaną z Objective-C protokołem dla określonego delegata, platforma Xamarin.iOS umożliwia również zaimplementowanie metod protokołu w dowolnej klasie pochodzącej z NSObjectklasy , dekorowanie metod za pomocą ExportAttributeelementu , a następnie podanie odpowiednich selektorów. W przypadku tego podejścia przypisujesz wystąpienie klasy do WeakDelegate właściwości zamiast do Delegate właściwości . Słaby delegat zapewnia elastyczność przechodzenia do klasy delegata w dół innej hierarchii dziedziczenia. Zobaczmy, jak zaimplementować i użyć słabego delegata w naszej aplikacji platformy Xamarin.iOS.

Utwórz program obsługi zdarzeń dla funkcji TouchUpInside — utwórzmy nową procedurę obsługi zdarzeń dla TouchUpInside zdarzenia przycisku Zmień kolor tła. Ta procedura obsługi wypełni tę samą rolę co HandleTouchUpInsideWithStrongDelegate procedura obsługi utworzona w poprzedniej sekcji, ale użyje słabego delegata zamiast silnego delegata. Edytuj klasę ViewControlleri dodaj następującą metodę:

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

Update ViewDidLoad — musimy zmienić element ViewDidLoad tak, aby używał właśnie utworzonej procedury obsługi zdarzeń. Edytuj ViewController i zmień ViewDidLoad , tak aby przypominał następujący fragment kodu:

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

Obsługa elementu colorPickerControllerDidFinish: Message — po ViewController zakończeniu system iOS wyśle komunikat colorPickerControllerDidFinish: do .WeakDelegate Musimy utworzyć metodę języka C#, która może obsłużyć ten komunikat. W tym celu utworzymy metodę języka C#, a następnie dodajemy ją do klasy ExportAttribute. Zmodyfikuj ViewControllermetodę i dodaj następującą metodę do klasy:

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

Uruchom aplikację. Powinien teraz zachowywać się dokładnie tak, jak wcześniej, ale używa słabego delegata zamiast silnego delegata. Na tym etapie pomyślnie ukończono ten przewodnik. Teraz musisz poznać sposób tworzenia i korzystania z projektu powiązania platformy Xamarin.iOS.

Podsumowanie

W tym artykule przedstawiono proces tworzenia i używania projektu powiązania platformy Xamarin.iOS. Najpierw omówiliśmy sposób kompilowania istniejącej Objective-C biblioteki w bibliotece statycznej. Następnie omówiliśmy sposób tworzenia projektu powiązania platformy Xamarin.iOS oraz używania języka Objective Sharpie do generowania definicji interfejsu Objective-C API dla biblioteki. Omówiliśmy sposób aktualizowania i dostosowywania wygenerowanych definicji interfejsu API w celu dostosowania ich do użytku publicznego. Po zakończeniu projektu powiązania platformy Xamarin.iOS przeprowadziliśmy się do korzystania z tego powiązania w aplikacji platformy Xamarin.iOS, koncentrując się na używaniu silnych delegatów i słabych delegatów.