Xamarin.iOS
Bindende snelle bibliotheken
Zoeken…
Invoering
Een eenvoudig te volgen gids die u door het proces van het binden van Swift .framework-bestanden leidt voor gebruik in een Xamarin-project.
Opmerkingen
Bij het bouwen van een bibliotheek in Xcode heeft het een optie om de snelle bibliotheken op te nemen. Niet doen! Ze worden in uw uiteindelijke app opgenomen als NAME.app/Frameworks/LIBRARY.framework/Frameworks/libswift*.dylib, maar ze moeten worden opgenomen als NAME.app/Frameworks/libswift*.dylib
U kunt deze informatie elders vinden, maar het is het vermelden waard: neem geen bitcode op in de bibliotheek. Vanaf nu bevat Xamarin geen Bitcode voor iOS en vereist Apple dat alle bibliotheken dezelfde architecturen ondersteunen.
Een snelle bibliotheek binden in Xamarin.iOS
Het binden van een snelle bibliotheek in Xamarin.iOS volgt hetzelfde proces voor Objective-C zoals getoond in https://developer.xamarin.com/guides/ios/advanced_topics/binding_objective-c/ , maar met enkele kanttekeningen.
- Een snelle klasse moet van NSObject erven om te kunnen binden.
- Swift-compiler vertaalt klassen- en protocolnamen in iets anders, tenzij u de @objc- annotatie (bijvoorbeeld @objc (MyClass)) in uw snelle klassen gebruikt om de expliciete objectieve c-naam op te geven.
- Tijdens runtime moet uw APP enkele snelle kernbibliotheken bevatten naast uw gebonden framework in een map met de naam Frameworks;
- Wanneer de app naar AppStore wordt gepusht, moet deze een SwiftSupport-map bevatten naast uw Payload-map. Die bevinden zich in het IPA-bestand.
Hier vindt u een eenvoudige voorbeeldbinding: https://github.com/Flash3001/Xamarin.BindingSwiftLibrarySample
En een volledig bindend voorbeeld: https://github.com/Flash3001/iOSCharts.Xamarin
Hieronder vindt u stappen:
1.1 Bereid de Swift-klassen voor die u wilt exporteren
Voor elke Swift-klasse die u wilt gebruiken, moet u ofwel erven van NSObject en de Objective-C-naam expliciet maken met behulp van de objc-annotatie. Anders genereert de Swift-compiler verschillende namen. Hieronder staat een voorbeeldcode van hoe een Swift-klasse eruit zou kunnen zien. Merk op dat het niet uitmaakt welke klasse het erft zolang de rootklasse erft van NSObject.
//Add this to specify explicit objective c name
@objc(MyClass)
open class MyClass: NSObject {
open func getValue() -> String
{
return "Value came from MyClass.swift!";
}
}
1.2 Bouw het framework
Schakel Bitcode uit. *
Gebouwd voor release voor Device en Simulator. *
- Niet alleen gerelateerd aan Swift binding.
2. Maak een dikke bibliotheek
Een framework bevat verschillende bestanden, degene die een beetje moet eten is NAME.framework / NAME (zonder extensie).
- Kopieer Release-iphoneos / NAME.framework naar NAME.framework
- Maak de FAT-bibliotheek met behulp van:
- lipo -create Release-iphonesimulator / NAME.framework / NAME Release-iphoneos / NAME.framework / NAME -output NAME.framework / NAME
- Kopieer de bestanden in Release-iphonesimulator / NAME.framework / Modules / NAME.swiftmodule naar NAME.framework / Modules / NAME.swiftmodule (tot nu toe bevatte het alleen bestanden van de iPhone)
3. Importeer de bibliotheek
Ik neem aan dat je het Binding-project al hebt gemaakt in Bestand -> Nieuw -> iOS -> Binding Library.
Xamarin ondersteunt het importeren van .frameworks. Klik met de rechtermuisknop op 'Native References' en klik op 'native referentie toevoegen'. Zoek het nieuw gemaakte vet-framework en voeg het toe.
4. Maak de ApiDefinition op basis van het bestand LIBRARY-Swift.h in headers.
Je kunt het handmatig doen, maar het zal niet leuk zijn. U kunt Objetive Sharpie gebruiken. De tool die Xamarin gebruikt om zijn eigen bibliotheken te binden.
Hoe het te gebruiken op https://developer.xamarin.com/guides/cross-platform/macios/binding/objective-sharpie/
Het basiscommando ziet er ongeveer zo uit: sharpie bind -sdk iphoneos9.3 NAME-Swift.h
Als u een System.Reflection.TargetInvocationException
, komt dit waarschijnlijk omdat u een andere SDK-versie hebt geïnstalleerd. Voer de volgende opdracht uit om te controleren met de iPhone OS SDK die u hebt geïnstalleerd:
sharpie xcode -sdks
Het bestand NAME-Swift.h bevindt zich in NAME.framework / Headers / NAME-Swift.h
Opmerking: De snelle klassen moeten erven van "NSObject", anders importeert NAME-Swift.h uw klassen niet en Objetive Sharpie converteert niets.
Vervang de inhoud van uw bindende project ApiDefinition.cs door het nieuw gemaakte project.
5. Wijzig alle [Protocol] en [BaseType] om de naam van de klasse op te nemen in Objective-C runtime.
In het geval dat de originele Swift-klasse of het protocol niet de annotatie @objc (MyClass) bevat zoals gespecificeerd in stap 1.1, zullen de interne Objective-C-namen worden gewijzigd, dus u moet deze aan de juiste toewijzen.
Alle namen zijn beschikbaar in het bestand NAME-Swift.h in de volgende indeling:
SWIFT_CLASS("_TtC11SwiftSample7MyClass")
@interface MyClass : NSObject
En
SWIFT_PROTOCOL("_TtP6Charts17ChartDataProvider_")
@protocol ChartDataProvider
Om de naam in te stellen, gebruikt u BaseTypeAttribute.Name https://developer.xamarin.com/guides/cross-platform/macios/binding/binding-types-reference/#BaseType.Name eigenschap voor klassen en ProcotolAttribute.Name https: // developer.xamarin.com/api/property/MonoTouch.Foundation.ProtocolAttribute.Name/ voor protocollen.
[BaseType(typeof(NSObject), Name = "_TtC11SwiftSample7MyClass")]
interface MyClass
Handmatig doen is niet cool. U kunt deze tool https://github.com/Flash3001/SwiftClassify gebruiken om alle namen in te voegen. (Het is werk in uitvoering. Maar het is vrij eenvoudig, alleen door naar de code te kijken, krijgt u hoe het werkt).
6.1 Omvat alle Swift-afhankelijkheden die moeten worden uitgevoerd.
Als u de bibliotheek in een app probeert te gebruiken en deze nu probeert uit te voeren, crasht deze. De fout is te wijten aan het ontbreken van libswiftCore.dylib
Iets zoals dit:
Dyld Error Message:
Library not loaded: @rpath/libswiftCore.dylib
Referenced from: /Users/USER/Library/Developer/CoreSimulator/Devices/AC440891-C819-4050-8CAB-CE15AB4B3830/data/Containers/Bundle/Application/27D2EC87-5042-4FA7-9B80-A24A8971FB48/SampleUsing.app/Frameworks/SwiftSample.framework/SwiftSample
Reason: image not found
Xamarin.iOS geeft geen officiële ondersteuning voor het binden van een Swift-bibliotheek. U moet dus de snelle kernbibliotheken handmatig opnemen in de mappen Frameworks en SwiftSupport. De bestanden voor de map Frameworks zijn verschillend voor Simulator en Apparaat. Ze zijn te vinden in /Applications/Xcode.app/Contents/Developer//XcodeDefault.xctoolchain/usr/lib/swift.Toolchains
In plaats van de bestanden in de Framework-map handmatig te kopiëren, kunt u deze bibliotheek https://github.com/Flash3001/Xamarin.Swift3.Support gebruiken . Het omvat elke afhankelijkheid die Swift 3.1 nodig heeft, elk in een enkel NuGet-pakket.
Zoals u kunt zien, is het Nuget-pakket opgenomen in de consumenten-app, niet in de binding zelf. Als u het in de binding probeert op te nemen, krijgt u compilatiefouten.
Als u een Nuget-pakket bouwt, kunt u Nuget de opdracht geven dit als afhankelijkheid op te nemen.
6.2. Uitzoeken welke Swift afhankelijkheden moeten worden opgenomen.
Een belangrijk ding om te doen is om elk pakket te berekenen dat u in uw project moet opnemen. Een eenvoudige binding vereist meestal:
libswiftCore.dylib
libswiftCoreGraphics.dylib
libswiftCoreImage.dylib
libswiftDarwin.dylib
libswiftDispatch.dylib
libswiftFoundation.dylib
libswiftObjectiveC.dylib
libswiftQuartzCore.dylib
libswiftUIKit.dylib
Om elke afhankelijkheid weer te geven, kunt u de volgende opdracht uitvoeren in uw LibraryName.framework
otool -l -arch armv7 LibraryName | grep libswift
Neem niet elk pakket op dat beschikbaar is in NuGet voor Swift3, omdat deze de grootte van uw app kunnen vergroten.
7. Neem SwiftSupport op om de app naar AppStore te duwen.
Apple vereist dat uw app wordt verzonden met een SwiftSupport-map naast uw Payload-map. Beide bevinden zich in uw IPA-pakket.
U kunt dit script https://github.com/bq/ipa-packager gebruiken om dit voor u te doen.
Dit proces is het enige dat de bibliotheekconsument handmatig moet doen. Elke keer als hij / zij probeert de app naar AppStore te duwen.
Klik op 'Ondertekenen en distribueren' en opslaan op schijf
Maak de nieuwe IPA met behulp van het eerder genoemde script
Als u het bestand weet uit te pakken, bevat het de map SwiftSupport.
Opmerkingen
Bij het bouwen van een bibliotheek in Xcode heeft het een optie om de snelle bibliotheken op te nemen. Niet doen! Ze worden in uw uiteindelijke app opgenomen als NAME.app/Frameworks/LIBRARY.framework/Frameworks/libswift*.dylib, maar ze moeten worden opgenomen als NAME.app/Frameworks/libswift*.dylib
U kunt deze informatie elders vinden, maar het is het vermelden waard: neem geen bitcode op in de bibliotheek. Vanaf nu bevat Xamarin geen Bitcode voor iOS en vereist Apple dat alle bibliotheken dezelfde architecturen ondersteunen.
ontkenning
Deze gids is oorspronkelijk gemaakt door Lucas Teixeira . Alle credits zijn van hem. Bedankt, Lucas.