Xamarin.iOS 集成第三方庫

最近公司用 Xamarin 開發(fā)的項(xiàng)目里需要集成一個(gè)第三方 SDK,名字叫做聽云,是一個(gè)應(yīng)用性能監(jiān)控的平臺(tái)。聽云提供的 SDK 是用 OC 寫的,而 Xamarin 要用的話需要先轉(zhuǎn)成它可以使用的形式,所以花了幾天時(shí)間研究這個(gè)東西。坑很多,我先踏為敬。

iOS 第三方庫一般分為靜態(tài)庫和動(dòng)態(tài)庫,前者通常以 .a 為后綴,后者以 .framework 為后綴。兩者的區(qū)別如下:

靜態(tài)庫(Static Library) — 源代碼編譯形成目標(biāo)文件的合集,本質(zhì)上是源代碼的實(shí)現(xiàn)所對應(yīng)的二進(jìn)制實(shí)現(xiàn)。配合上一起提供的 .h 文件,可以獲取到靜態(tài)庫中暴露的屬性和方法。

動(dòng)態(tài)庫(Dynamic Framework) — 相當(dāng)于一個(gè)隨時(shí)可調(diào)用包,比如 iOS SDK 的 UIKit 之類的系統(tǒng)庫就是動(dòng)態(tài)庫。相比靜態(tài)庫來說,動(dòng)態(tài)庫不需要 .h 文件就可以直接調(diào)用,而且只需要加載一次,對程序的執(zhí)行效率相對于靜態(tài)庫有所提高。

動(dòng)態(tài)庫相比靜態(tài)庫有許多優(yōu)點(diǎn),可以控制加載時(shí)機(jī),這意味著通過服務(wù)端下發(fā)動(dòng)態(tài)庫可以對 App 實(shí)現(xiàn)熱更新,包括但不局限與修復(fù) bug,同時(shí)也可以動(dòng)態(tài)更新 App 界面布局和業(yè)務(wù)邏輯,也就意味著可以像前端一樣,拋棄版本的概念,所有用戶每次進(jìn)入應(yīng)用獲取的都是最新版。

但遺憾的是,Apple 不允許第三方框架使用動(dòng)態(tài)庫,只有系統(tǒng)框架可以通過動(dòng)態(tài)方式加載。不然廣大開發(fā)者又何必費(fèi)盡心思搞出各種 patch,各種混合開發(fā)框架又怎會(huì)大行其道,一聲嘆息啊。

下面以一個(gè)最近做的例子,聽云 SDK 的集成,來具體說明下如何將 OC 原生動(dòng)態(tài)庫轉(zhuǎn)換成 Xamarin.iOS 能夠使用的 dll 動(dòng)態(tài)鏈接庫。

下載下來的 SDK 目錄如下所示:

聽云 SDK 目錄

首先將圖中用紅框圈起來的文件 tingyunApp 名稱改為 tingyunApp.a,然后需要用到 Sharpie 這個(gè) Xamarin 官方提供的命令行工具,可以在官方網(wǎng)站下載安裝。安裝完成之后,在終端 cd 到 Headers 的上一級,鍵入下面的命令:

sharpie bind --output=tingyunApp.iOS --namespace=tingyunApp.iOS --sdk=iphoneos10.2 /Users/xxpang/Desktop/tingyun/tingyunApp.framework/Versions/A/Headers/NBSAppAgent.h /Users/xxpang/Desktop/tingyun/tingyunApp.framework/Versions/A/Headers/NBSGCDOverrider.h

如果路徑?jīng)]錯(cuò)的話,在終端可以看到如下界面:

終端成功生成 Binding 文件的界面

然后在 Finder 用戶文件夾下可以看到生成的 tingyunApp.iOS 文件夾,里面有剛才生成的 ApiDefinitions.cs 和 StructsAndEnums.cs 兩個(gè)文件。

至此,我們完成了將 OC 庫 轉(zhuǎn)為 C# 庫的第一步。下面在 Xamarin Studio 里新建一個(gè) Binding Library 項(xiàng)目,如下所示:

選擇 Bindings Library 類型的項(xiàng)目

新建的 Binding Library 項(xiàng)目目錄結(jié)構(gòu)如下:

新建的項(xiàng)目目錄結(jié)構(gòu)

下一步就用到我們第一步里改名的文件:tingyunApp.a,在 本機(jī)引用 上右擊 Add Native Reference,將 framework 中的 tingyunApp.a 添加到項(xiàng)目中,然后在添加的文件上右擊屬性,在 IDE 右側(cè)出現(xiàn)的面板里填寫需要用到的系統(tǒng)庫,比如 Security.framework、CoreTelephony.framework 等,如果需要添加 libz.tbd 等類庫的話,需要在 Linker Flags 后面加上相應(yīng)描述,具體如下圖所示:

編輯 tingyunApp.iOS 的屬性面板

完成這些之后,下面需要進(jìn)行的是將命令行生成的兩個(gè)文件里面的內(nèi)容,復(fù)制替換掉原來的內(nèi)容,需要注意的是,namespace 名稱需要跟項(xiàng)目名稱保持一致。替換完成后,正常情況下編譯運(yùn)行是會(huì)報(bào)錯(cuò)的,這是做 Xamarin 應(yīng)該有的基本覺悟了。當(dāng)然,如果你編譯通過了,說明你很幸運(yùn),恭喜。

Sharpie 這個(gè)命令行工具的原理,是將 OC 的頭文件以及對應(yīng)的方法實(shí)現(xiàn),一一映射成 C# 可以直接調(diào)用的方法,再結(jié)合 tingyunApp.a 文件生成 Xamarin 可以使用的類庫,原理如下圖所示。

Sharpie 的作用

上面說了,Sharpie 的作用是將原生庫里的方法一一映射成 C# 的類和方法,類似的還有他們用 C# 重寫了 iOS SDK 的所有方法。不過呢,說是一一映射,還是有一些不合適的轉(zhuǎn)換,所以才會(huì)編譯報(bào)錯(cuò),接下來會(huì)是一個(gè)比較痛苦的過程。

ApiDefinition.h 文件內(nèi)容

如上圖所示,在 ApiDefinition.h 文件中我們可以看到很多劃紅線的地方,這些有的不影響編譯和運(yùn)行,有的會(huì)影響,又不能簡單粗暴地刪除或者注釋,因?yàn)樗麄兌紝?yīng)著原生庫里面的方法,不處理又不能編譯運(yùn)行通過。

Structs.h 文件內(nèi)容

如上圖,在 Structs.h 文件中有一些 [Verify] 標(biāo)簽,這些標(biāo)簽是系統(tǒng)用來提示開發(fā)者需要確認(rèn)的地方,修改完錯(cuò)誤之后需要?jiǎng)h掉。說到這里就得再說一個(gè)大坑了,官方提供了一個(gè)原生方法和 C# 方法轉(zhuǎn)換方法的說明,歡迎點(diǎn)擊 Binding Types Reference 查看學(xué)習(xí)。這就要求你既懂 OC 的語法,又要懂 C# 的語法,不然有些報(bào)錯(cuò)無法處理,話說回來,如果已經(jīng)會(huì) OC 了,為什么還要用這個(gè)坑如此多的東西。。

成功編譯之后生成的 dll 文件

言歸正傳,修改完上面那些 bug,編譯運(yùn)行通過之后,我們的工作基本就完成了。之后打開 Finder 在項(xiàng)目文件夾的 bin -> debug 目錄下可以找到生成的 dll 文件,引入到需要的項(xiàng)目里就可以使用了。至此,OC 的 framework 轉(zhuǎn)為 C# 的 dll 就完成了,祝你一切順利!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容