Compartilhar via


Demonstra Passo a passo: Vinculando uma biblioteca do iOS Objective-C

Importante

No momento, estamos investigando o uso de vinculação personalizada na plataforma Xamarin. Por favor, faça esta pesquisa para informar os futuros esforços de desenvolvimento.

Este artigo fornece um passo a passo prático da criação de uma associação Xamarin.iOS para uma biblioteca existente Objective-C , InfColorPicker. Ele aborda tópicos como compilar uma biblioteca estática Objective-C , vinculá-la e usar a associação em um aplicativo Xamarin.iOS.

Ao trabalhar no iOS, você pode encontrar casos em que deseja consumir uma biblioteca de terceiros Objective-C . Nessas situações, você pode usar um Projeto de Vinculação Xamarin.iOS para criar uma vinculação C# que permitirá que você consuma a biblioteca em seus aplicativos Xamarin.iOS.

Geralmente no ecossistema iOS você pode encontrar bibliotecas em 3 sabores:

  • Como um arquivo de biblioteca estática pré-compilado com extensão junto com .a seu(s) cabeçalho(s) (arquivos .h). Por exemplo, a Biblioteca do Google Analytics
  • Como um Framework pré-compilado. Esta é apenas uma pasta contendo a biblioteca estática, cabeçalhos e, às vezes, recursos adicionais com .framework extensão. Por exemplo, a Biblioteca AdMob do Google.
  • Como apenas arquivos de código-fonte. Por exemplo, uma biblioteca contendo arquivos apenas .m e .h Objective C.

No primeiro e segundo cenário, já haverá uma Biblioteca Estática CocoaTouch pré-compilada, então neste artigo vamos nos concentrar no terceiro cenário. Lembre-se, antes de começar a criar uma associação, sempre verifique a licença fornecida com a biblioteca para garantir que você esteja livre para vinculá-la.

Este artigo fornece um passo a passo da criação de um projeto de vinculação usando o projeto InfColorPicker de código aberto como exemplo, no entanto, todas as informações neste guia podem ser adaptadas para uso com qualquer biblioteca de terceirosObjective-C.Objective-C A biblioteca InfColorPicker fornece um controlador de exibição reutilizável que permite ao usuário selecionar uma cor com base em sua representação HSB, tornando a seleção de cores mais fácil de usar.

Example of the InfColorPicker library running on iOS

Abordaremos todas as etapas necessárias para consumir essa API específica Objective-C no Xamarin.iOS:

  • Primeiro, criaremos uma Objective-C biblioteca estática usando o Xcode.
  • Em seguida, vincularemos essa biblioteca estática ao Xamarin.iOS.
  • Em seguida, mostre como o Objective Sharpie pode reduzir a carga de trabalho gerando automaticamente algumas (mas não todas) das definições de API necessárias exigidas pela associação Xamarin.iOS.
  • Finalmente, criaremos um aplicativo Xamarin.iOS que usa a associação.

O aplicativo de exemplo demonstrará como usar um delegado forte para comunicação entre a API InfColorPicker e nosso código C#. Depois de vermos como usar um delegado forte, abordaremos como usar delegados fracos para executar as mesmas tarefas.

Requisitos

Este artigo pressupõe que você tenha alguma familiaridade com o Xcode e a linguagem e tenha lido Objective-C nossa documentação de vinculaçãoObjective-C. Além disso, é necessário o seguinte para concluir as etapas apresentadas:

  • Xcode e iOS SDK - O Xcode da Apple e a API iOS mais recente precisam ser instalados e configurados no computador do desenvolvedor.
  • Ferramentas de linha de comando do Xcode - As ferramentas de linha de comando do Xcode devem ser instaladas para a versão atualmente instalada do Xcode (veja abaixo os detalhes da instalação).
  • Visual Studio para Mac ou Visual Studio - A versão mais recente do Visual Studio para Mac ou Visual Studio deve ser instalada e configurada no computador de desenvolvimento. Um Apple Mac é necessário para desenvolver um aplicativo Xamarin.iOS e, ao usar o Visual Studio, você deve estar conectado a um host de compilação Xamarin.iOS
  • A última versão do Objective Sharpie - Uma cópia atual da ferramenta Objective Sharpie baixada aqui. Se você já tiver o Objective Sharpie instalado, poderá atualizá-lo para a versão mais recente usando o sharpie update

Instalando as ferramentas de linha de comando do Xcode

Como dito acima, usaremos as Ferramentas de Linha de Comando do Xcode (especificamente make e lipo) neste passo a passo. O make comando é um utilitário Unix muito comum que automatizará a compilação de programas executáveis e bibliotecas usando um makefile que especifica como o programa deve ser construído. O lipo comando é um utilitário de linha de comando do OS X para criar arquivos multi-arquitetura, ele combinará vários .a arquivos em um arquivo que pode ser usado por todas as arquiteturas de hardware.

De acordo com a documentação Building from the Command Line with Xcode FAQ da Apple, no OS X 10.9 e superior, o painel Downloads da caixa de diálogo Preferências do Xcode não suporta mais as ferramentas de linha de comando de download.

Você precisará usar um dos seguintes métodos para instalar as ferramentas:

  • Instalar o Xcode - Quando você instala o Xcode , ele vem junto com todas as suas ferramentas de linha de comando. No OS X 10.9 shims (instalado no /usr/bin), pode mapear qualquer ferramenta incluída na /usr/bin ferramenta correspondente dentro do Xcode. Por exemplo, o xcrun comando, que permite localizar ou executar qualquer ferramenta dentro do Xcode a partir da linha de comando.

  • O aplicativo Terminal - A partir do aplicativo Terminal, você pode instalar as ferramentas de linha de comando executando o xcode-select --install comando:

    • Inicie o aplicativo de terminal.
    • Digite xcode-select --install e pressione Enter, por exemplo:
    Europa:~ kmullins$ xcode-select --install
    
    • Você será solicitado a instalar as ferramentas de linha de comando, clique no botão Instalar : Installing the command line tools

    • As ferramentas serão baixadas e instaladas a partir dos servidores da Apple: Downloading the tools

  • Downloads para desenvolvedores da Apple - O pacote de ferramentas de linha de comando está disponível na página da Web Downloads para desenvolvedores da Apple. Inicie sessão com o seu ID Apple e, em seguida, procure e transfira as Ferramentas de Linha de Comando: Finding the Command Line Tools

Com as Ferramentas de Linha de Comando instaladas, estamos prontos para continuar com o passo a passo.

Passo a passo

Neste passo a passo, abordaremos as seguintes etapas:

Agora que entendemos quais etapas estão envolvidas, vamos passar para o resto do passo a passo.

Criando uma biblioteca estática

Se inspecionarmos o código do InfColorPicker no Github:

Inspect the code for InfColorPicker in Github

Podemos ver os três diretórios a seguir no projeto:

  • InfColorPicker - Este diretório contém o código para o Objective-C projeto.
  • PickerSamplePad - Este diretório contém um projeto iPad de exemplo.
  • PickerSamplePhone - Este diretório contém um projeto de iPhone de exemplo.

Vamos baixar o projeto InfColorPicker do GitHub e descompactá-lo no diretório de nossa escolha. Abrindo o destino Xcode para PickerSamplePhone o projeto, vemos a seguinte estrutura de projeto no Xcode Navigator:

The project structure in the Xcode Navigator

Este projeto obtém a reutilização de código adicionando diretamente o código-fonte InfColorPicker (na caixa vermelha) em cada projeto de exemplo. O código para o projeto de exemplo está dentro da caixa azul. Como este projeto em particular não nos fornece uma biblioteca estática, é necessário que criemos um projeto Xcode para compilar a biblioteca estática.

A primeira etapa é adicionarmos o código-fonte do InfoColorPicker à Biblioteca Estática. Para conseguir isso, vamos fazer o seguinte:

  1. Inicie o Xcode.

  2. No menu Arquivo, selecione Novo>Projeto...:

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

  3. Selecione Framework & Library, o modelo Cocoa Touch Static Library e clique no botão Next:

    Select the Cocoa Touch Static Library template

  4. Digite InfColorPicker o Nome do Projeto e clique no botão Avançar:

    Enter InfColorPicker for the Project Name

  5. Selecione um local para salvar o projeto e clique no botão OK .

  6. Agora precisamos adicionar o código-fonte do projeto InfColorPicker ao nosso projeto de biblioteca estática. Como o arquivo InfColorPicker.h já existe em nossa biblioteca estática (por padrão), o Xcode não nos permitirá substituí-lo. No Finder, navegue até o código-fonte do InfColorPicker no projeto original que descompactamos do GitHub, copie todos os arquivos do InfColorPicker e cole-os em nosso novo projeto de biblioteca estática:

    Copy all of the InfColorPicker files

  7. Volte para o Xcode, clique com o botão direito do mouse na pasta InfColorPicker e selecione Adicionar arquivos ao "InfColorPicker...":

    Adding files

  8. Na caixa de diálogo Adicionar arquivos, navegue até os arquivos de código-fonte do InfColorPicker que acabamos de copiar, selecione-os todos e clique no botão Adicionar :

    Select all and click the Add button

  9. O código fonte será copiado em nosso projeto:

    The source code will be copied into the project

  10. No Xcode Project Navigator, selecione o arquivo InfColorPicker.m e comente as duas últimas linhas (devido à maneira como essa biblioteca foi escrita, esse arquivo não é usado):

    Editing the InfColorPicker.m file

  11. Agora precisamos verificar se há algum Frameworks exigido pela biblioteca. Você pode encontrar essas informações no LEIA-ME ou abrindo um dos projetos de exemplo fornecidos. Este exemplo usa Foundation.framework, UIKit.frameworke CoreGraphics.framework então vamos adicioná-los.

  12. Selecione as fases de compilação de destino do InfColorPicker e expanda a seção Vincular binário com bibliotecas:>

    Expand the Link Binary With Libraries section

  13. Use o + botão para abrir a caixa de diálogo permitindo que você adicione as estruturas de quadros necessárias listadas acima:

    Add the required frames frameworks listed above

  14. A seção Link Binary With Libraries agora deve se parecer com a imagem abaixo:

    The Link Binary With Libraries section

Neste momento estamos perto, mas ainda não terminamos. A biblioteca estática foi criada, mas precisamos compilá-la para criar um binário Fat que inclua todas as arquiteturas necessárias para o dispositivo iOS e o simulador iOS.

Criando um binário gordo

Todos os dispositivos iOS têm processadores alimentados pela arquitetura ARM que se desenvolveram ao longo do tempo. Cada nova arquitetura adicionava novas instruções e outras melhorias, mantendo a compatibilidade com versões anteriores. Os dispositivos iOS têm conjuntos de instruções armv6, armv7, armv7s, arm64 – embora o armv6 não seja mais usado. O simulador iOS não é alimentado por ARM e, em vez disso, é um simulador x86 e x86_64 alimentado. Isso significa que bibliotecas devem ser fornecidas para cada conjunto de instruções.

Uma biblioteca Fat é .a um arquivo que contém todas as arquiteturas suportadas.

Criar um binário gordo é um processo de três etapas:

  • Compile uma versão ARM 7 & ARM64 da biblioteca estática.
  • Compile uma versão x86 e x84_64 da biblioteca estática.
  • Use a lipo ferramenta de linha de comando para combinar as duas bibliotecas estáticas em uma.

Embora essas três etapas sejam bastante simples, pode ser necessário repeti-las no futuro quando a Objective-C biblioteca receber atualizações ou se precisarmos de correções de bugs. Se você decidir automatizar essas etapas, isso simplificará a manutenção e o suporte futuros do projeto de vinculação do iOS.

Há muitas ferramentas disponíveis para automatizar essas tarefas - um shell script, rake, xbuild e make. Quando as ferramentas de linha de comando do Xcode são instaladas, também é instalado, make de modo que é o sistema de compilação que será usado para esta explicação passo a passo. Aqui está um Makefile que você pode usar para criar uma biblioteca compartilhada de várias arquiteturas que funcionará em um dispositivo iOS e no simulador para qualquer biblioteca:

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

Insira os comandos Makefile no editor de texto simples de sua escolha e atualize as seções com YOUR-PROJECT-NAME com o nome do seu projeto. Também é importante garantir que você cole as instruções acima exatamente, com as abas dentro das instruções preservadas.

Salve o arquivo com o nome Makefile no mesmo local que a biblioteca estática InfColorPicker Xcode que criamos acima:

Save the file with the name Makefile

Abra o Aplicativo Terminal no Mac e navegue até o local do Makefile. Digite make no Terminal, pressione Enter e o Makefile será executado:

Sample makefile output

Quando você executar make, você verá um monte de texto rolando por. Se tudo funcionou corretamente, você verá as palavras BUILD SUCCESSFUL e o , e libInfColorPickerSDK.a os arquivos serão libInfColorPicker-i386.a copiados para o mesmo local que o libInfColorPicker-armv7.aMakefile:

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

Você pode confirmar as arquiteturas dentro do binário Fat usando o seguinte comando:

xcrun -sdk iphoneos lipo -info libInfColorPicker.a

Isso deve exibir o seguinte:

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

Neste ponto, concluímos a primeira etapa de nossa vinculação do iOS criando uma biblioteca estática usando o Xcode e as ferramentas make Xcode Command Line e lipo. Vamos passar para a próxima etapa e usar o Objective-Sharpie para automatizar a criação das associações de API para nós.

Criar um projeto de vinculação Xamarin.iOS

Antes de podermos usar o Objective-Sharpie para automatizar o processo de vinculação, precisamos criar um Projeto de Vinculação Xamarin.iOS para abrigar as Definições de API (que usaremos o Objective-Sharpie para nos ajudar a criar) e criar a vinculação C# para nós.

Vamos fazer o seguinte:

  1. Inicie o Visual Studio para Mac.

  2. No menu Arquivo, selecione Nova>Solução...:

    Starting a new solution

  3. Na caixa de diálogo Nova Solução, selecione Projeto de Vinculação do iOS da Biblioteca>:

    Select iOS Binding Project

  4. Clique no botão Avançar.

  5. Digite "InfColorPickerBinding" como o nome do projeto e clique no botão Criar para criar a solução:

    Enter InfColorPickerBinding as the Project Name

A solução será criada e dois arquivos padrão serão incluídos:

The solution structure in the Solution Explorer

  • ApiDefinition.cs - Esse arquivo conterá os contratos que definem como Objective-C as APIs serão encapsuladas em C#.
  • Structs.cs - Esse arquivo armazenará quaisquer estruturas ou valores de enumeração exigidos pelas interfaces e delegados.

Trabalharemos com esses dois arquivos mais adiante no passo a passo. Primeiro, precisamos adicionar a biblioteca InfColorPicker ao projeto de vinculação.

Incluindo a biblioteca estática no projeto de vinculação

Agora temos nosso projeto base de vinculação pronto, precisamos adicionar a biblioteca Fat Binary que criamos acima para a biblioteca InfColorPicker .

Siga estas etapas para adicionar a biblioteca:

  1. Clique com o botão direito do mouse na pasta Referências Nativas no Painel de Soluções e selecione Adicionar Referências Nativas:

    Add Native References

  2. Navegue até o Fat Binary que fizemos anteriormente (libInfColorPickerSDK.a) e pressione o botão Abrir :

    Select the libInfColorPickerSDK.a file

  3. O arquivo será incluído no projeto:

    Including a file

Quando o arquivo .a é adicionado ao projeto, o Xamarin.iOS definirá automaticamente a Ação de compilação do arquivo como ObjcBindingNativeLibrary e criará um arquivo especial chamado libInfColorPickerSDK.linkwith.cs.

Esse arquivo contém o atributo que informa ao LinkWith Xamarin.iOS como lidar com a biblioteca estática que acabamos de adicionar. O conteúdo desse arquivo é mostrado no seguinte trecho de código:

using ObjCRuntime;

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

O LinkWith atributo identifica a biblioteca estática para o projeto e alguns sinalizadores de vinculador importantes.

A próxima coisa que precisamos fazer é criar as definições de API para o projeto InfColorPicker. Para os fins deste passo a passo, usaremos o Objective Sharpie para gerar o arquivo ApiDefinition.cs.

Usando o Objective Sharpie

O Objective Sharpie é uma ferramenta de linha de comando (fornecida pelo Xamarin) que pode ajudar na criação das definições necessárias para vincular uma biblioteca de terceiros 3rd ao Objective-C C#. Nesta seção, usaremos o Objective Sharpie para criar o ApiDefinition inicial .cs para o projeto InfColorPicker.

Para começar, vamos baixar o arquivo do instalador do Objective Sharpie conforme detalhado neste guia. Execute o instalador e siga todos os prompts na tela do assistente de instalação para instalar o Objective Sharpie em nosso computador de desenvolvimento.

Depois de termos o Objective Sharpie instalado com sucesso, vamos iniciar o aplicativo Terminal e inserir o seguinte comando para obter ajuda sobre todas as ferramentas que ele fornece para ajudar na vinculação:

sharpie -help

Se executarmos o comando acima, a seguinte saída será gerada:

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

Para o propósito deste passo a passo, usaremos as seguintes ferramentas do Objective Sharpie:

  • xcode - Esta ferramenta nos dá informações sobre nossa instalação atual do Xcode e as versões das APIs do iOS e Mac que instalamos. Usaremos essas informações mais tarde, quando gerarmos nossas vinculações.
  • bind - Usaremos essa ferramenta para analisar os arquivos .h no projeto InfColorPicker nos arquivos iniciais ApiDefinition.cs e StructsAndEnums.cs .

Para obter ajuda sobre uma ferramenta específica do Objective Sharpie, digite o nome da ferramenta e a -help opção. Por exemplo, sharpie xcode -help retorna a seguinte saída:

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.

Antes de iniciarmos o processo de vinculação, precisamos obter informações sobre nossos SDKs instalados atualmente inserindo o seguinte comando no Terminal 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

Pelo exposto, podemos ver que temos o iphoneos9.3 SDK instalado em nossa máquina. Com essas informações, estamos prontos para analisar os arquivos de projeto InfColorPicker no ApiDefinition inicial.cs e StructsAndEnums.cs para o projeto .h InfColorPicker.

Digite o seguinte comando no aplicativo Terminal:

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

Onde [full-path-to-project] é o caminho completo para o diretório onde o arquivo de projeto InfColorPicker Xcode está localizado em nosso computador, e [iphone-os] é o SDK do iOS que instalamos, como observado pelo sharpie xcode -sdks comando. Observe que neste exemplo passamos *.h como um parâmetro, que inclui todos os arquivos de cabeçalho neste diretório - normalmente você NÃO deve fazer isso, mas em vez disso, ler cuidadosamente os arquivos de cabeçalho para encontrar o arquivo .h de nível superior que faz referência a todos os outros arquivos relevantes, e apenas passar isso para o Objective Sharpie.

Dica

Para o -scope argumento, passe na pasta que tem os cabeçalhos que você deseja vincular. Sem o argumento, o Objective Sharpie tentará gerar ligações para quaisquer cabeçalhos do SDK do iOS que forem importados, por exemplo, resultando em um enorme arquivo de definições que provavelmente gerará erros ao compilar o -scope projeto de vinculação. #import <UIKit.h> Com o argumento definido, o -scope Objective Sharpie não gerará associações para nenhum cabeçalho fora da pasta com escopo.

A seguinte saída será gerada no terminal:

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$

E os arquivos InfColorPicker.enums.cs e InfColorPicker.cs serão criados em nosso diretório:

The InfColorPicker.enums.cs and InfColorPicker.cs files

Abra esses dois arquivos no projeto Binding que criamos acima. Copie o conteúdo do arquivo InfColorPicker.cs e cole-o no arquivo ApiDefinition.cs, substituindo o bloco de código existente namespace ... pelo conteúdo do arquivo InfColorPicker.cs (deixando as instruções intactas):using

The InfColorPickerControllerDelegate file

Normalizar as definições de API

Objetivo Sharpie às vezes tem um problema de Delegatestradução, então precisaremos modificar a definição da interface e substituir a InfColorPickerControllerDelegate[Protocol, Model] linha com o seguinte:

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

Para que a definição se pareça com:

The definition

Em seguida, fazemos a mesma coisa com o conteúdo do InfColorPicker.enums.cs arquivo, copiando-os e colando-os StructsAndEnums.cs no arquivo deixando as using instruções intactas:

The contents the StructsAndEnums.cs file

Você também pode descobrir que o Objective Sharpie anotou a vinculação com [Verify] atributos. Esses atributos indicam que você deve verificar se a Objective Sharpie fez a coisa correta, comparando a vinculação com a declaração C/Objective-C original (que será fornecida em um comentário acima da declaração vinculada). Depois de verificar as associações, você deve remover o atributo verify. Para obter mais informações, consulte o Guia de verificação .

Neste ponto, nosso projeto de vinculação deve estar completo e pronto para ser construído. Vamos construir nosso projeto de vinculação e garantir que acabamos sem erros:

Crie o projeto de vinculação e verifique se não há erros

Usando a vinculação

Siga estas etapas para criar um aplicativo de iPhone de exemplo para usar a Biblioteca de Vinculação do iOS criada acima:

  1. Criar projeto Xamarin.iOS - Adicione um novo projeto Xamarin.iOS chamado InfColorPickerSample à solução, conforme mostrado nas seguintes capturas de tela:

    Adding a Single View App

    Setting the Identifier

  2. Adicionar referência ao projeto de vinculação - Atualize o projeto InfColorPickerSample para que ele tenha uma referência ao projeto InfColorPickerBinding:

    Adding Reference to the Binding Project

  3. Criar a interface do usuário do iPhone - Clique duas vezes no arquivo MainStoryboard.storyboard no projeto InfColorPickerSample para editá-lo no iOS Designer. Adicione um Button ao modo de exibição e chame-o ChangeColorButton, conforme mostrado a seguir:

    Adding a Button to the view

  4. Adicione o InfColorPickerView.xib - A biblioteca InfColorPicker inclui um arquivo .xib.Objective-C O Xamarin.iOS não incluirá esse .xib no projeto de vinculação, o que causará erros em tempo de execução em nosso aplicativo de exemplo. A solução alternativa para isso é adicionar o arquivo .xib ao nosso projeto Xamarin.iOS. Selecione o projeto Xamarin.iOS, clique com o botão direito do mouse e selecione Adicionar > arquivos e adicione o arquivo .xib conforme mostrado na captura de tela a seguir:

    Add the InfColorPickerView.xib

  5. Quando solicitado, copie o arquivo .xib para o projeto.

Em seguida, vamos dar uma rápida olhada em Protocolos em e como lidamos com eles em Objective-C vinculação e código C#.

Protocolos e Xamarin.iOS

No Objective-C, um protocolo define métodos (ou mensagens) que podem ser usados em determinadas circunstâncias. Conceitualmente, eles são muito semelhantes às interfaces em C#. Uma grande diferença entre um Objective-C protocolo e uma interface C# é que os protocolos podem ter métodos opcionais - métodos que uma classe não precisa implementar. Objective-C usa a @optional palavra-chave é usada para indicar quais métodos são opcionais. Para obter mais informações sobre protocolos, consulte Eventos, protocolos e representantes.

InfColorPickerController tem um desses protocolos, mostrado no trecho de código abaixo:

@protocol InfColorPickerControllerDelegate

@optional

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

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

@end

Esse protocolo é usado por InfColorPickerController para informar aos clientes que o usuário escolheu uma nova cor e que o InfColorPickerController foi concluído. O Objective Sharpie mapeou esse protocolo conforme mostrado no seguinte trecho de código:

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

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

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

Quando a biblioteca de vinculação é compilada, o Xamarin.iOS criará uma classe base abstrata chamada InfColorPickerControllerDelegate, que implementa essa interface com métodos virtuais.

Há duas maneiras de implementar essa interface em um aplicativo Xamarin.iOS:

  • Delegado forte - Usar um delegado forte envolve a criação de uma classe C# que subclasse InfColorPickerControllerDelegate e substitui os métodos apropriados. InfColorPickerController usará uma instância dessa classe para se comunicar com seus clientes.
  • Delegado fraco - Um delegado fraco é uma técnica ligeiramente diferente que envolve a criação de um método público em alguma classe (como InfColorPickerSampleViewController) e, em seguida, a exposição desse InfColorPickerDelegate método ao protocolo por meio de um Export atributo.

Delegados fortes fornecem Intellisense, segurança de tipo e melhor encapsulamento. Por esses motivos, você deve usar delegados fortes onde puder, em vez de um delegado fraco.

Neste passo a passo, discutiremos ambas as técnicas: primeiro implementar um delegado forte e, em seguida, explicar como implementar um delegado fraco.

Implementando um delegado forte

Conclua o aplicativo Xamarin.iOS usando um delegado forte para responder à colorPickerControllerDidFinish: mensagem:

Subclasse InfColorPickerControllerDelegate - Adicione uma nova classe ao projeto chamado ColorSelectedDelegate. Edite a classe para que ela tenha o seguinte código:

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

O Xamarin.iOS vinculará o Objective-C delegado criando uma classe base abstrata chamada InfColorPickerControllerDelegate. Subclassifique esse tipo e substitua o ColorPickerControllerDidFinish método para acessar o ResultColor valor da propriedade de InfColorPickerController.

Criar uma instância de ColorSelectedDelegate - Nosso manipulador de eventos precisará de uma instância do ColorSelectedDelegate tipo que criamos na etapa anterior. Edite a classe e adicione a seguinte variável de instância à classe InfColorPickerSampleViewController :

ColorSelectedDelegate selector;

Inicialize a variável ColorSelectedDelegate - Para garantir que selector seja uma instância válida, atualize o método ViewDidLoad para corresponder ViewController ao seguinte trecho:

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

Implemente o método HandleTouchUpInsideWithStrongDelegate - Em seguida, implemente o manipulador de eventos para quando o usuário tocar em ColorChangeButton. Edite ViewControllere adicione o seguinte método:

using InfColorPicker;
...

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

Primeiro, obtemos uma instância de por meio de um método estático e tornamos essa instância ciente de InfColorPickerController nosso delegado forte por meio da propriedade InfColorPickerController.Delegate. Esta propriedade foi gerada automaticamente para nós pela Objective Sharpie. Finalmente, chamamos PresentModallyOverViewController para mostrar a visualização InfColorPickerSampleViewController.xib para que o usuário possa selecionar uma cor.

Executar o aplicativo - Neste ponto, terminamos com todo o nosso código. Se você executar o aplicativo, você deve ser capaz de alterar a cor de plano de fundo do como mostrado nas seguintes capturas de InfColorColorPickerSampleView tela:

Running the Application

Parabéns! Neste ponto, você criou e vinculou com êxito uma Objective-C biblioteca para uso em um aplicativo Xamarin.iOS. Em seguida, vamos aprender sobre como usar delegados fracos.

Implementando um delegado fraco

Em vez de subclassificar uma classe vinculada ao protocolo para um delegado específico, o Objective-C Xamarin.iOS também permite implementar os métodos de protocolo em qualquer classe derivada de NSObject, decorando seus métodos com o ExportAttribute, e fornecendo os seletores apropriados. Ao adotar essa abordagem, você atribui uma instância de sua classe à propriedade em vez de à WeakDelegateDelegate propriedade. Um delegado fraco oferece a flexibilidade de levar sua classe de delegado para uma hierarquia de herança diferente. Vamos ver como implementar e usar um delegado fraco em nosso aplicativo Xamarin.iOS.

Create Event Handler for TouchUpInside - Vamos criar um novo manipulador de eventos para o TouchUpInside evento do botão Alterar Cor do Plano de Fundo. Esse manipulador preencherá a mesma função que o HandleTouchUpInsideWithStrongDelegate manipulador que criamos na seção anterior, mas usará um delegado fraco em vez de um delegado forte. Edite a classe ViewControllere adicione o seguinte método:

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

Update ViewDidLoad - Devemos alterar ViewDidLoad para que ele use o manipulador de eventos que acabamos de criar. Edite ViewController e altere ViewDidLoad para se parecer com o seguinte trecho de código:

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

Manipular o colorPickerControllerDidFinish: Mensagem - Quando o for concluído, o iOS enviará a mensagem colorPickerControllerDidFinish: para o ViewControllerWeakDelegate. Precisamos criar um método C# que possa manipular essa mensagem. Para fazer isso, criamos um método C# e, em seguida, adorná-lo com o ExportAttribute. Edite ViewControllere adicione o seguinte método à classe:

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

Execute o aplicativo. Agora deve se comportar exatamente como antes, mas está usando um delegado fraco em vez do delegado forte. Neste ponto, você concluiu com êxito este passo a passo. Agora você deve ter uma compreensão de como criar e consumir um projeto de vinculação Xamarin.iOS.

Resumo

Este artigo percorreu o processo de criação e uso de um projeto de vinculação Xamarin.iOS. Primeiro, discutimos como compilar uma biblioteca existente Objective-C em uma biblioteca estática. Em seguida, abordamos como criar um projeto de vinculação Xamarin.iOS e como usar o Objective Sharpie para gerar as definições de API para a Objective-C biblioteca. Discutimos como atualizar e ajustar as definições de API geradas para torná-las adequadas para consumo público. Depois que o projeto de vinculação do Xamarin.iOS foi concluído, passamos a consumir essa vinculação em um aplicativo Xamarin.iOS, com foco no uso de delegados fortes e delegados fracos.