繫結 Xamarin.iOS 中的 Swift 庫
繫結 Xamarin.iOS 中的 Swift 庫遵循與 Objective-C 相同的過程,如 https://developer.xamarin.com/guides/ios/advanced_topics/binding_objective-c/ 所示,但有一些注意事項。
- swift 類必須從 NSObject 繼承才能繫結。
- 除非在 swift 類中使用 @objc 註釋(例如 @
objc(MyClass)
)來指定顯式目標 c 名稱,否則 Swift 編譯器會將類和協議名稱轉換為其他名稱。 - 在執行時,你的 APP 必須在名為 Frameworks 的資料夾中包含一些快速核心庫以及繫結框架;
- 當應用程式被推送到 AppStore 時,它必須在你的 Payload 資料夾旁邊包含一個 SwiftSupport 資料夾。這些都在 IPA 檔案中。
在這裡你可以找到一個簡單的樣本繫結: https : //github.com/Flash3001/Xamarin.BindingSwiftLibrarySample
以及完整的繫結示例: https : //github.com/Flash3001/iOSCharts.Xamarin
請找到以下步驟:
1.1 準備要匯出的 Swift 類
對於你要使用的任何 Swift 類,你必須從 NSObject 繼承並使用 objc 註釋顯式顯示 Objective-C 名稱。否則 Swift 編譯器將生成不同的名稱。下面是 Swift 類的外觀示例程式碼。請注意,只要根類繼承自 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 構建框架
禁用 Bitcode。 *
構建適用於裝置和模擬器的版本。 *
- 與 Swift 繫結無關。
2.建立一個胖庫
一個框架包含幾個檔案,需要吃一點的是 NAME.framework / NAME(沒有副檔名)。
- 將 Release-iphoneos / NAME.framework 複製到 NAME.framework
- 使用以下命令建立 FAT 庫:
- lipo -create Release-iphonesimulator / NAME.framework / NAME Release-iphoneos / NAME.framework / NAME -output NAME.framework / NAME
- 將 Release-iphonesimulator / NAME.framework / Modules / NAME.swiftmodule 中的檔案複製到 NAME.framework / Modules / NAME.swiftmodule(直到現在它只包含來自 iphoneos 的檔案)
3.匯入庫
我假設你已經在 File - > New - > iOS - > Binding Library 中建立了 Binding 專案。
Xamarin 支援匯入 .frameworks。只需右鍵單擊 Native References
,然後單擊 Add native reference
。找到新建立的胖框架並新增它。
4.根據標頭檔案中的 LIBRARY-Swift.h 檔案建立 ApiDefinition
你可以手動完成它,但它不會很好。你可以使用 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:
sharpie xcode -sdks
NAME-Swift.h 檔案位於 NAME.framework / Headers / NAME-Swift.h 中
注意:swift 類必須繼承自 NSObject
,否則 NAME-Swift.h 將不會匯入你的類,而 Objetive Sharpie 將不會轉換任何內容。
用新建立的專案替換繫結專案 ApiDefinition.cs 的內容。
5.更改所有[Protocol]和[BaseType]以在 Objective-C 執行時中包含類的名稱
如果原始 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")]
interface MyClass
手動完成並不酷。你可以使用此工具 https://github.com/Flash3001/SwiftClassify 插入所有名稱。 (它正在進行中。但它非常簡單,只需檢視程式碼就可以瞭解它的工作原理)。
6.1 包括要執行的所有 Swift 依賴項
如果你嘗試在應用程式中使用該庫並嘗試立即執行它將崩潰。錯誤是由於缺少 libswiftCore.dylib
像這樣的東西:
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 沒有為繫結 Swift 庫提供官方支援。因此,你必須在 Frameworks 和 SwiftSupport 資料夾中手動包含 swift 核心庫。Frameworks 資料夾的檔案對於 Simulator 和 Device 是不同的。它們可以在/Applications/Xcode.app/Contents/Developer//XcodeDefault.xctoolchain/usr/lib/swift.Toolchains 中找到
你可以使用此庫 https://github.com/Flash3001/Xamarin.Swift3.Support 而不是手動複製 Framework 資料夾中的檔案。它包括 Swift 3.1 所需的每個依賴項,每個依賴項都在一個 NuGet 包中。
如你所見,Nuget Package 包含在消費者 App 中,而不是繫結本身。如果你嘗試將其包含在繫結中,則會出現編譯錯誤。
如果你正在構建 Nuget 包,則可以指示 Nuget 將其作為依賴項包含在內。
6.2。找出要包含的 Swift 依賴項
一件重要的事情是弄清楚你需要包含在專案中的每個包。通常需要一個簡單的繫結:
libswiftCore.dylib
libswiftCoreGraphics.dylib
libswiftCoreImage.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 中包含所有可用的包,因為它們可能會增加你的應用程式大小。
7.包括 SwiftSupport 以將 App 推送到 AppStore
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 要求所有庫都支援相同的架構。
放棄
本指南最初由 Lucas Teixeira 建立。所有學分屬於他。謝謝你,盧卡斯。