绑定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要求所有库都支持相同的体系结构。