绑定Swift库— Xamarin.iOS
这篇文章最初发布在Stack Overflow文档上,许多其他人对此做出了贡献,不幸的是,无法找到他们是谁。 如果您对此做出了贡献,请告诉我,以便我们给予适当的感谢。
易于遵循的指南,将引导您完成绑定Swift .framework文件以用于Xamarin项目的过程。
1.在Xcode中构建库时,可以选择包含swift库。 别! 它们将以NAME.app/Frameworks/LIBRARY.framework/Frameworks/libswift * .dylib的形式包含在您的最终应用程序中, 但是必须以NAME.app/Frameworks/libswift* .dylib的形式包含在其中。
2.您可以在其他地方找到此信息,但值得一提:不要在库中包含Bitcode。 截至目前,Xamarin尚未包括适用于iOS的Bitcode,Apple要求所有库都支持相同的体系结构。
在Xamarin.iOS中绑定Swift库的iOS对Objective-C遵循与https://developer.xamarin.com/guides/ios/advanced _topics / binding_objective -c /中所示的相同过程,但有一些警告。
1.一个快速类必须从NSObject继承才能绑定。
2. Swift编译器会将类和协议名称转换为其他名称,除非您在swift类中使用[@objc]批注(例如@objc(MyClass))来指定显式目标c名称。
3.在运行时,您的APP必须在名为Frameworks的文件夹中包含一些快速核心库以及绑定的框架。
4.将应用程序推送到AppStore时,它必须在Payload文件夹旁边包括一个SwiftSupport文件夹。 这些都在IPA文件中。
在这里您可以找到一个简单的示例绑定:https://github.com/Flash3001/Xamarin.BindingSwiftLibrarySample
以及完整的绑定示例:https://github.com/Flash3001/iOSCharts.Xamarin
对于您要使用的任何Swift类,您都必须继承自NSObject,并使用objc注释使Objective-C名称显式。 否则,Swift编译器将生成不同的名称。 下面是一个示例代码,说明Swift类的外观。 注意,只要根类继承自NSObject,它继承哪个类都没有关系。
//添加它以指定明确的目标c名称
@objc(MyClass)
打开类MyClass:NSObject {
打开func getValue()->字符串
{
返回“值来自MyClass.swift!”;
}
}
1.2建立框架
禁用位码。 *
为设备和模拟器发布而构建。 *
*仅与Swift绑定无关。
一个框架包含几个文件,一个需要吃一点的文件是NAME.framework / NAME(不带扩展名)。
–将Release-iphoneos / NAME.framework复制到NAME.framework
–使用以下方法创建FAT库:
– lipo -create Release-iphonesimulator / NAME.framework / NAME Release-iphoneos / NAME.framework / NAME-输出NAME.framework / NAME
–将Release-iphonesimulator / NAME.framework / Modules / NAME.swiftmodule中的文件复制到NAME.framework / Modules / NAME.swiftmodule(直到现在仅包含来自iphoneos的文件)
我假设您已经在File-> New-> iOS-> Binding Library中创建了Binding项目。
Xamarin支持导入.frameworks。 只需右键单击“本地参考”,然后单击“添加本地参考”。 找到新创建的胖框架并将其添加。
您可以手动执行操作,但效果不佳。 您可以使用Objetive Sharpie。 Xamarin用来绑定其自己的库的工具。
如何在https://developer.xamarin.com/guides/cross-platform/macios/binding/objective-sharpie/上使用它
基本命令如下所示: sharpie bind -sdk iphoneos9.3 NAME-Swift.h
如果得到` System.Reflection.TargetInvocationException` ,则可能是因为您安装了不同的SDK版本。 运行以下命令以检查是否已安装iPhone OS SDK:
夏普xcode -sdks
文件NAME-Swift.h位于NAME.framework / Headers / NAME-Swift.h中
注意:swift类必须继承自“ NSObject”,否则NAME-Swift.h将不会导入您的类,而Objetive Sharpie将不进行任何转换。
将绑定项目ApiDefinition.cs的内容替换为新创建的内容。
如果原始Swift类或协议不包含步骤1.1中指定的@objc(MyClass)批注,则它们的内部Objective-C名称将发生更改,因此您需要将其映射到正确的名称。
所有名称在文件NAME-Swift.h中都可用,格式如下:
SWIFT_CLASS(“ _ TtC11SwiftSample7MyClass”)
@interface MyClass:NSObject
和
SWIFT_PROTOCOL(“ _ TtP6Charts17ChartDataProvider_”)
@protocol ChartDataProvider
要设置名称,请使用BaseTypeAttribute.Name https://developer.xamarin.com/guides/cross-platform/macios/binding/binding-types-reference/#BaseType.Name属性和ProcotolAttribute.Name https:// developer.xamarin.com/api/property/MonoTouch.Foundation.ProtocolAttribute.Name/用于协议。
[BaseType(typeof(NSObject),Name =“ _TtC11SwiftSample7MyClass”)]
接口MyClass
手动操作并不酷。 您可以使用此工具https://github.com/Flash3001/SwiftClassify插入所有名称。 (它正在进行中。但是它很简单,只需查看代码,您就会知道它是如何工作的)。
如果您尝试在应用程序中使用该库并尝试立即运行它,它将崩溃。 该错误是由于缺少libswiftCore.dylib
像这样:
Dyld错误消息:
库未加载:@ rpath / libswiftCore.dylib
引用自:/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
原因:找不到图片
Xamarin.iOS不提供绑定Swift库的官方支持。 因此,您必须在Frameworks和SwiftSupport文件夹中手动包含swift核心库。 Simulator和Device的Frameworks文件夹的文件不同。 可以在/Applications/Xcode.app/Contents/Developer//XcodeDefault.xctoolchain/usr/lib/swift.Toolchains中找到它们
您可以使用此库https://github.com/Flash3001/Xamarin.Swift3.Support来代替手动复制Framework文件夹中的文件。 它包括Swift 3.1需要的每个依赖项,每个都包含在单个NuGet包中。
如您所见,Nuget包包含在消费者应用程序中,而不包含在绑定本身中。 如果尝试将其包含在绑定中,则会出现编译错误。
如果要构建Nuget软件包,则可以指示Nuget将其作为依赖项包括在内。
6.2。 找出要包含的Swift依赖项。
重要的事情是弄清楚需要包含在项目中的每个软件包。 一个简单的绑定通常需要:
libswiftCore.dylib
libswiftCoreGraphics.dylib
libswiftCoreImage.dylib
libswiftCoreFoundation.dylib
libswiftDarwin.dylib
libswiftDispatch.dylib
libswiftFoundation.dylib
libswiftObjectiveC.dylib
libswiftQuartzCore.dylib
libswiftUIKit.dylib
要列出每个依赖项,可以在LibraryName.framework中运行以下命令
otool -l -arch armv7 LibraryName
grep libswift
不要包括NuGet for Swift3中可用的每个软件包,因为它们可能会增加您的应用程序大小。
Apple要求您的应用程序必须与Payload文件夹一起发送SwiftSupport文件夹。 两者都在IPA包中。
您可以使用此脚本https://github.com/bq/ipa-packager为您完成此工作。
此过程是库使用者必须手动执行的唯一过程。 每次他/她尝试将App推送到AppStore时。
点击“签名并分发”并保存到磁盘
解压缩您的.IPA
使用前面提到的脚本创建新的IPA
如果您知道将文件解压缩,它将包含SwiftSupport文件夹。
在Xcode中构建库时,可以选择包含swift库。 别! 它们将以NAME.app/Frameworks/LIBRARY.framework/Frameworks/libswift * .dylib的形式包含在您的最终应用程序中, 但是必须以NAME.app/Frameworks/libswift* .dylib的形式包含在其中。
您可以在其他地方找到此信息,但值得一提:不要在库中包含Bitcode。 截至目前,Xamarin尚未包括适用于iOS的Bitcode,Apple要求所有库都支持相同的体系结构。