Exemplo de Real-World avançado (manual)
Este exemplo usa a biblioteca POP do Facebook.
Esta seção aborda uma abordagem mais avançada de associação, em que usaremos a ferramenta da xcodebuild
Apple para primeiro criar o projeto POP e, em seguida, deduzir manualmente a entrada para Objective Sharpie. Isso essencialmente aborda o que o Objective Sharpie está fazendo sob os bastidores da seção anterior.
$ git clone https://github.com/facebook/pop.git
Cloning into 'pop'...
_(more git clone output)_
$ cd pop
Como a biblioteca POP tem um projeto Xcode (pop.xcodeproj
), podemos usar xcodebuild
apenas para criar POP. Esse processo pode, por sua vez, gerar arquivos de cabeçalho que o Objective Sharpie pode precisar analisar. É por isso que criar antes da associação é importante. Ao criar por meio xcodebuild
do verifique se você passa o mesmo identificador e arquitetura do SDK que pretende passar para o Objective Sharpie (e lembre-se, o Objective Sharpie 3.0 geralmente pode fazer isso por você!):
$ xcodebuild -sdk iphoneos9.0 -arch arm64
Build settings from command line:
ARCHS = arm64
SDKROOT = iphoneos8.1
=== BUILD TARGET pop OF PROJECT pop WITH THE DEFAULT CONFIGURATION (Release) ===
...
CpHeader pop/POPAnimationTracer.h build/Headers/POP/POPAnimationTracer.h
cd /Users/aaron/src/sharpie/pop
export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/Users/aaron/bin::/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/git/bin:/Users/aaron/.rvm/bin"
builtin-copy -exclude .DS_Store -exclude CVS -exclude .svn -exclude .git -exclude .hg -strip-debug-symbols -strip-tool /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/strip -resolve-src-symlinks /Users/aaron/src/sharpie/pop/pop/POPAnimationTracer.h /Users/aaron/src/sharpie/pop/build/Headers/POP
...
** BUILD SUCCEEDED **
Haverá muita saída de informações de build no console como parte do xcodebuild
. Conforme exibido acima, podemos ver que um destino "CpHeader" foi executado em que arquivos de cabeçalho foram copiados para um diretório de saída de build. Geralmente, esse é o caso e facilita a associação: como parte do build da biblioteca nativa, os arquivos de cabeçalho geralmente são copiados para um local consumível "publicamente", o que pode facilitar a análise da associação. Nesse caso, sabemos que os arquivos de cabeçalho do POP estão no build/Headers
diretório.
Agora estamos prontos para associar POP. Sabemos que queremos criar para o SDK iphoneos8.1
com a arm64
arquitetura e que os arquivos de cabeçalho com os quais nos preocupamos estão no build/Headers
check-out do git POP. Se examinarmos o build/Headers
diretório, veremos vários arquivos de cabeçalho:
$ ls build/Headers/POP/
POP.h POPAnimationTracer.h POPDefines.h
POPAnimatableProperty.h POPAnimator.h POPGeometry.h
POPAnimation.h POPAnimatorPrivate.h POPLayerExtras.h
POPAnimationEvent.h POPBasicAnimation.h POPPropertyAnimation.h
POPAnimationExtras.h POPCustomAnimation.h POPSpringAnimation.h
POPAnimationPrivate.h POPDecayAnimation.h
Se examinarmos POP.h
, podemos ver que é o main arquivo de cabeçalho de nível superior da biblioteca que #import
são outros arquivos. Por causa disso, só precisamos passar POP.h
para Objective Sharpie, e clang fará o resto nos bastidores:
$ sharpie bind -output Binding -sdk iphoneos8.1 \
-scope build/Headers build/Headers/POP/POP.h \
-c -Ibuild/Headers -arch arm64
Parsing Native Code...
Binding...
[write] ApiDefinitions.cs
[write] StructsAndEnums.cs
Binding Analysis:
Automated binding is complete, but there are a few APIs which have
been flagged with [Verify] attributes. While the entire binding
should be audited for best API design practices, look more closely
at APIs with the following Verify attribute hints:
ConstantsInterfaceAssociation (1 instance):
There's no fool-proof way to determine with which Objective-C
interface an extern variable declaration may be associated.
Instances of these are bound as [Field] properties in a partial
interface into a near-by concrete interface to produce a more
intuitive API, possibly eliminating the 'Constants' interface
altogether.
StronglyTypedNSArray (4 instances):
A native NSArray* was bound as NSObject[]. It might be possible
to more strongly type the array in the binding based on
expectations set through API documentation (e.g. comments in the
header file) or by examining the array contents through testing.
For example, an NSArray* containing only NSNumber* instances can
be bound as NSNumber[] instead of NSObject[].
MethodToProperty (2 instances):
An Objective-C method was bound as a C# property due to
convention such as taking no parameters and returning a value (
non-void return). Often methods like these should be bound as
properties to surface a nicer API, but sometimes false-positives
can occur and the binding should actually be a method.
Once you have verified a Verify attribute, you should remove it
from the binding source code. The presence of Verify attributes
intentionally cause build failures.
For more information about the Verify attribute hints above,
consult the Objective Sharpie documentation by running 'sharpie
docs' or visiting the following URL:
http://xmn.io/sharpie-docs
Submitting usage data to Xamarin...
Submitted - thank you for helping to improve Objective Sharpie!
Done.
Você observará que passamos um -scope build/Headers
argumento para Objective Sharpie. Como as bibliotecas C e Objective-C devem #import
ou #include
outros arquivos de cabeçalho que são detalhes de implementação da biblioteca e não da API que você deseja associar, o -scope
argumento informa ao Objective Sharpie para ignorar qualquer API que não esteja definida em um arquivo em algum lugar dentro do -scope
diretório.
Você descobrirá que o -scope
argumento geralmente é opcional para bibliotecas implementadas de forma limpa, no entanto, não há nenhum dano em forizá-lo explicitamente.
Dica
Se os cabeçalhos da biblioteca importarem cabeçalhos do SDK do iOS, por exemplo #import <Foundation.h>
, , você precisará definir o escopo caso contrário, o Objective Sharpie gerará definições de associação para o cabeçalho do SDK do iOS que foi importado, resultando em uma associação enorme que provavelmente gerará erros ao compilar o projeto de associação.
Além disso, especificamos -c -Ibuild/headers
. Em primeiro lugar, o -c
argumento instrui Objective Sharpie a parar de interpretar argumentos de linha de comando e passar quaisquer argumentos subsequentes diretamente para o compilador clang. Portanto, -Ibuild/Headers
é um argumento do compilador clang que instrui clang a pesquisar por inclusões em build/Headers
, que é onde os cabeçalhos POP residem. Sem esse argumento, clang não saberia onde localizar os arquivos que POP.h
estão #import
sendo usados. Quase todos os "problemas" com o uso do Objective Sharpie se resumem a descobrir o que passar para clang.
Concluindo a associação
O Objective Sharpie já gerou Binding/ApiDefinitions.cs
arquivos e Binding/StructsAndEnums.cs
.
Estes são a primeira passagem básica do Objective Sharpie na associação e, em alguns casos, pode ser tudo o que você precisa. Conforme indicado acima, no entanto, o desenvolvedor geralmente precisará modificar manualmente os arquivos gerados após a conclusão do Objective Sharpie para corrigir quaisquer problemas que não puderam ser tratados automaticamente pela ferramenta.
Depois que as atualizações forem concluídas, esses dois arquivos agora poderão ser adicionados a um projeto de associação no Visual Studio para Mac ou serem passados diretamente para as btouch
ferramentas ou bmac
para produzir a associação final.
Para obter uma descrição completa do processo de associação, consulte nossas instruções passo a passo completas.