Artykuł

freeimages.com freeimages.com
lis 29 2016
0

Targetowanie paczek pod różne systemy w Xamarnie

Tworząc biblioteki do rozwiązań Xamarinowych, właściwie nigdy nie myślimy tylko o jednym systemie docelowym. To w końcu dlatego przecież wybraliśmy właśnie rozwiązanie Microsoftu, by nie ograniczać się do jednej platformy. I o ile twórcy Xamarina starają się reklamować to rozwiązanie jako takie, w którym odsetek współdzielonego kodu jest niezwykle wysoki, to w praktyce nawet we wdrożeniach opartych o Xamarin.Forms nie da się uniknąć rozwiązań dedykowanych pod konkretne platformy.

Na szczęście nie jest to wielkie wyzwanie. Wystarczy tylko odpowiednio przygotować projekt oraz plik nuspec naszej wynikowej paczki:)

Konfiguracja

Być może we wstępie nie do końca precyzyjnie wytłumaczyłem w czym dokładnie tkwi problem, dlatego już spieszę z wyjaśnieniem na bazie przykładu praktycznego. Wyobraźmy sobie, że mamy projekt o nazwie MyPackage, który docelowo ma wspierać Androida oraz iOS. Jego bazowa struktura folderów/plików może wyglądać mniej więcej tak:

MyPackage/
    bin/
        $configuration$/
            MyPackage.dll
    obj/
    MyPackage.csproj
    MyPackage.nuspec
MyPackage.Lib.Droid
    bin/
        $configuration$/
            MyPackage.Lib.Droid.dll
    obj/
    MyPackage.Lib.Droid.csproj
MyPackage.Lib.iOS
    bin/
        $configuration$/
            MyPackage.Lib.iOS.dll
    obj/
    MyPackage.Lib.iOS.csproj    
MyPackage.sln

Zmienna $configuration$ określa wybraną podczas budowania paczki konfigurację np. x86, x64, Any Cpu itp.

Cała solucja składa się z trzech projektów, z których każdy generuje wynikową DLLkę. Pierwszy zawiera część wspólną, czyli przeważnie w przypadku Xamarina jest to biblioteka o profilu 111 (ze względu na wciąż ograniczone wsparcie dla .Net Standard Library używam w tym tekście referencji do profili). Dwa kolejne skierowane są już pod konkretne platformy. Paczka wygenerowana w oparciu o plik nuspec z lokalizacji biblioteki Portable, nie będzie domyślnie zawierać dedykowanych paczek dla Androida oraz iOS. Nawet gdybyśmy je załączyli w standardowy, to i tak nie zainstalują się one prawidłowo w docelowych projektach. Rozwiązaniem tego problemu będzie zastosowanie atrybutu target:

<?xml version="1.0"?>
<package>
	<metadata>
		<!-- normal nuspec -->
	</metadata>
	<files>
		<file src="bin\$configuration$\MyPackage.dll" target="lib\MonoAndroid10\" />
		<file src="..\MyPackage.Lib.Droid\bin\$configuration$\MyPackage.Lib.Droid.dll" target="lib\MonoAndroid10\" />
		<file src="bin\$configuration$\MyPackage.dll" target="lib\xamarinios10\" />
		<file src="..\MyPackage.Lib.iOS\bin\$configuration$\MyPackage.Lib.iOS.dll" target="lib\xamarinios10\" />
	</files>
</package>

Taki kod da nam wynikową paczkę ze strukturą zbliżoną do poniższej:

lib/
    MonoAndroid10/
        MyPackage.dll
        MyPackage.Lib.Droid.dll
    portable-net45%2Bwp8%2Bwpa81%2Bwin8%2BMonoAndroid10%2BMonoTouch10%2BXamarinIOS10/
        MyPackage.dll
    Xamarin.iOS10/
        MyPackage.dll
        MyPackage.Lib.iOS.dll

Co ciekawe, powyższe targety zawierają wersje bazowe. Przykładowo jeśli DLLka dla Androida została kompilowana przy użyciu Android SDK 7.0, to możliwe jest wskazanie targetu MonoAndroid70. Dzięki temu możemy w jednej paczce trzymać różne wersje bibliotek nawet w zależności od docelowego poziomu SDK:)

Tak przygotowany plik nuspec spowoduje, że niezależnie jaki target docelowy wybierzemy z puli obsługiwanych to i tak otrzyma on wszystkie niezbędne DLLki.

Data ostatniej modyfikacji: 30.11.2016, 08:02.

Podoba Ci się ten wpis? Powiedz o tym innym!

Send to Kindle

Komentarze

blog comments powered by Disqus