之前開發(fā)了一個 IM 通訊軟件在公司內(nèi)部使用,現(xiàn)在需要將 IM 以 SDK 的方式集成到另外一個 OA 應(yīng)用中蚌堵。對比了下兩個工程,OA 應(yīng)用是屬于比較老舊的那種沛婴,全部以 OC 實現(xiàn)吼畏,并且依賴的第三方庫比較老舊而且都是以代碼集成方式管理,甚至對部分三方庫做了修改嘁灯。IM 是通過 Pods 進行第三方依賴庫的管理泻蚊,和 OA 共用若干庫。由于是要求 IM 提供 SDK丑婿,加上 OA 不愿意修改他們的工程藕夫,所以我們只能以 SDK 的方式給他們提供Framework包孽糖。考慮到可能有的代碼沖突毅贮,我們決定一些 兩方都使用的UI 相關(guān)的庫办悟,在要求 UI 統(tǒng)一的情況下,拿出OA 的源碼打包成 framework滩褥,雙方共用病蛉。其余的非交叉的庫各自引用各自的互不干擾,OA 使用源碼集成瑰煎,IM 使用 Pods 集成 framework铺然。
IM 工程是 OC 和 Swift 混編的,在 Application 工程中酒甸,對于這種混編的解決方案也很簡單魄健,只要增加橋接頭文件就可以了。但是在 Framework 工程中插勤,是不需要橋接文件的沽瘦。那在 Framework 工程中如何做到混編的呢?
1农尖、首先當(dāng)你新建一個 Framework 工程時析恋,Xcode 的工程模板是會自動生成極簡情況下的工程文件,其中有一個非常重要的文件盛卡,$(TARGET_NAME).h 文件助隧。這個文件是作為 Framework 將內(nèi)部方法暴露給外部調(diào)用的一個 Public 入口頭文件,系統(tǒng)幫你默認生成的滑沧。
2并村、新建 Podfile,如下編寫:
這里需要注意滓技,使用 Swift 的 Framework 都必須在 Podfile 中寫上 use_frameworks!原因如下兩個:
A橘霎、用CocoaPods 導(dǎo)入swift 框架 到 swift項目和OC項目都必須要 use_frameworks!
B、使用 dynamic frameworks殖属,必須要在Podfile文件中添加 use_frameworks!
2、選擇 PROJECR/TARGET -> Build Settings -> Allow non-modular includes in Framework Modules -> YES
注意: Project 和 Target 需要同時設(shè)置瓦盛。
因為新版本的 Pods 的方式是將第三方庫制作成Dynamic Frameworks洗显,相當(dāng)于在 MyFramework 中引用別的 Framework,需要告訴編譯器允許這種行為原环。
3挠唆、將 Swift 文件中用到的 OC 文件的頭文件包含到 MyFramework.h 中,并且將對應(yīng)的頭文件放到 Target -> Buid Phases -> Headers -> Public 中嘱吗。這里需要注意的是玄组,就算你在 Swift 代碼中直接引用第三方庫的方法滔驾,你也不需要將第三方庫的頭文件引用放到 MyFramework.h 中,只需要將你自己用到的 OC 頭文件放入其中即可俄讹。原因第四點會講哆致。
4、編譯工程患膛,你會收到編譯成功的通知摊阀。進入 Products 目錄,你會發(fā)現(xiàn) Products 目錄下有如下幾個文件:
你會發(fā)現(xiàn)編譯結(jié)果為自己的 Framework 和第三方的 Framework踪蹬,包括 Pods 生成的引用 Framework(只是引用胞此,并沒有將第三方庫打包到其中)。如果你要向別人提供 MyFramework.framework 跃捣,別人是無法編譯通過的漱牵,因為MyFramework.framework中僅包含它自己的源碼而不包括第三放庫的,因為蘋果禁止在Dynamic Frameworks使用 Framework疚漆。所以你需要將所有的 Framework 都交付給第三方酣胀,除了 Pods生成的Framework。至此MyFramework 生成結(jié)束愿卸。
你可能會有疑問灵临,如此引入會不會有編譯問題。那這里可以探討下趴荸。
一般集成第三方庫的方式有如下三種:
A儒溉、直接將第三方庫的源碼集成到工程中;
B发钝、將第三方庫打包成 Static Library 集成到工程中顿涣;
C、將第三方庫打包成 Framework 集成酝豪;
其中 A涛碑、B 兩種方式是一樣的,都需要鏈接第三方庫的源碼孵淘,只是 Static Library 是提前編譯好了蒲障。如果第三方工程采用 A 方式集成第三方庫,正如我遇到的情況瘫证,就算我們使用了相同的第三方庫揉阎,也不會發(fā)生錯誤,因為他使用本地文件背捌,頭文件的引用方式和使用 Framework 的引用方式是不一樣的毙籽,可以說兩者是在不同的 NameSpace 中,編譯器在編譯和鏈接的過程中并不會發(fā)生錯誤毡庆。甚至 MyFramework 中可以使用與第三方相同的文件和類名坑赡,只要他在使用時文件中不同時引用MyFramework的頭文件烙如。
最后,鑒于Dynamic Frameworks 的優(yōu)勢毅否,本人還是不推薦使用 AB 兩種方式集成第三方庫亚铁,除非萬不得已。
以下為參考資料:
pods 使用方法:http://www.reibang.com/p/ad2e37e741bb
http://www.samirchen.com/create-a-framework/
https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html
http://stackoverflow.com/questions/24175697/how-do-i-use-cocoapods-in-an-embedded-framework
http://www.tuicool.com/articles/Q3q6ry
https://guides.cocoapods.org/syntax/podfile.html
https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/CreationGuidelines.html#//apple_ref/doc/uid/20002254-BAJHGGGA