如何將第三方靜態(tài)庫封裝進(jìn)動態(tài)庫

隨著動態(tài)庫的流行鞭铆,靜態(tài)庫越來越少了(關(guān)于動態(tài)庫和靜態(tài)庫的介紹請點(diǎn)擊)矛市,但是不排除項(xiàng)目中有些依賴的第三方還是使用的靜態(tài)庫。那么這種情況下就可以考慮优俘,將第三方靜態(tài)庫做一個二次封裝京办。一來和業(yè)務(wù)代碼進(jìn)行隔離,方便以后第三方庫的升級帆焕,二來將靜態(tài)庫封裝進(jìn)動態(tài)庫里便于管理和利用動態(tài)庫的優(yōu)勢臂港。一般情況下,用動態(tài)庫封裝靜態(tài)庫很簡單视搏,就是將靜態(tài)庫直接拖進(jìn)動態(tài)庫的工程里审孽,直接編譯即可。但是有一種情況下這么做是不行的浑娜,需要暴露靜態(tài)庫的頭文件佑力,也就是雖然靜態(tài)庫放在動態(tài)庫里面了,但是靜態(tài)庫的頭文件還要提供給上層應(yīng)用調(diào)用筋遭。
下面以封裝百度地圖為例打颤,介紹如何將第三方靜態(tài)庫封裝進(jìn)動態(tài)庫。
百度地圖根據(jù)業(yè)務(wù)不同漓滔,劃分了很多不同的包编饺,大概包括基礎(chǔ)包、定位包响驴、地圖包透且、搜索包、工具包、全景包等秽誊。如下圖所示:

百度地圖包
這些包雖然是以.framework為后綴鲸沮,但是都是靜態(tài)庫。
首先锅论,新建一個動態(tài)庫工程讼溺,直接將這些包拖入到工程中。
集成百度地圖包
但是這時沒有辦法在BaiduMapKit.h中對外暴露頭文件最易,因?yàn)榘俣鹊貓D的頭文件都在.framework里面怒坯。如果不暴露頭文件,也就意味著應(yīng)用層無法調(diào)用藻懒。
BaiduMapKit.h文件
遇到這種情況敬肚,解決思路有三種。

第一種束析,用代碼將百度地圖庫封裝一層。

也就是自己代碼調(diào)用百度地圖庫憎亚,然后將自己代碼對外暴露员寇,供應(yīng)用層調(diào)用。這是最好的一種思路第美,不僅能解決問題蝶锋,還能將第三方庫和自己的項(xiàng)目業(yè)務(wù)隔離去耦合。對于一般的庫(比較小的庫)什往,非常推薦這種思路扳缕。但是對于百度地圖來說,不好執(zhí)行别威,因?yàn)榘俣鹊貓D的API太多太復(fù)雜了躯舔,如果一點(diǎn)一點(diǎn)去封裝,工作量太大了省古。當(dāng)然有人說粥庄,不一定要將所有的API都重新封裝,用到哪些才封裝哪些豺妓,這樣當(dāng)然是可以的惜互。不過還是挺困難的,百度地圖里面定義的類型太多了琳拭,哪怕是只用地圖這一個功能的API训堆,工作量都挺大。
第一種思路

第二種白嘁,將百度地圖的.framework包拆開為.a和.h文件坑鱼。

上面提到,在.framework里面的頭文件沒辦法對外暴露絮缅,那么把.framework這層殼去掉呢姑躲?

.framework本質(zhì)上只是一個文件夾睡扬,而靜態(tài)庫.framework文件夾里面其實(shí)是.a文件和其頭文件.h,把.framework文件夾去掉之后黍析,就可以把里面的.h頭文件暴露出去了卖怜。一般的庫這么做是可以的,也比較方便阐枣,但對于百度地圖來說马靠,是不行的。原因很簡單蔼两,百度地圖各個包之間有依賴關(guān)系甩鳄,即各包之間存在引用關(guān)系。去掉.framework文件夾和不去掉额划,引用方式是不一樣的妙啃。.framework文件夾引用方式是使用尖括號import <xxx/xxx.h>,去掉之后引用方式就變成了普通文件的引用import "xxx.h"俊戳。百度地圖各包之間的引用肯定是import <xxx/xxx.h>揖赴,如果去掉.framework文件夾,引用方式變了抑胎,也就導(dǎo)致文件找不到燥滑,編譯不成功。
.framework拆包

第三種阿逃,為百度地圖的.framework包額外添加.h頭文件铭拧。

上面討論了,對.framework拆包這種方式不適用于百度地圖恃锉,所以還得想其他辦法搀菩。比如,.framework包不動破托,然后在.framework包外再額外加一份頭文件呢秕磷?事實(shí)證明,這樣完全是可以的炼团。
額外增加頭文件

最終就是以這種方式解決問題澎嚣。方法雖然很簡單,但是需要想法瘟芝。所以思路和想法非常重要易桃。最終封裝的形式如下圖所示,demo請點(diǎn)擊锌俱。

最終方案

后續(xù)晤郑。。。

最近因?yàn)殡[私政策的原因造寝,需要再一次升級百度地圖磕洪。百度地圖已經(jīng)升級到6.5.1了。本來以為輕松替換一下靜態(tài)庫就可以完事诫龙,但是還是出幺蛾子了析显,百度地圖的幾個靜態(tài)庫替換之后,只要外面使用了百度地圖里面的類签赃,就會報(bào)類找不到錯誤谷异,也不知道百度地圖修改了什么導(dǎo)致的。如下圖所示:


升級后報(bào)錯

經(jīng)過一番折騰锦聊,還是沒有搞定歹嘹,因此確定之前的方案不行了,得另覓出路了孔庭。于是又想到了前面說的第一種方案尺上,這種方案是兜底的,是一定可行的圆到,但是就是比較麻煩怎抛。那么有沒有既可行又簡單一點(diǎn)的方案呢?還真有构资。這次在第一種方案的基礎(chǔ)上進(jìn)行了改良和優(yōu)化,形成了第四種方案陨簇。

第四種吐绵,對百度地圖類進(jìn)行擴(kuò)展。

說通俗一點(diǎn)河绽,就是自己創(chuàng)建一個類己单,繼承百度地圖中需要用到的類,對外暴露自己創(chuàng)建的類耙饰,這樣就避免了在framework外面直接使用百度的類纹笼,就不會報(bào)上面的錯誤了。

例如苟跪,需要使用到百度地圖的BMKMapManager類廷痘,在BaiduMapKit.framework中自己創(chuàng)建一個MyMapManager類繼承自BMKMapManager,然后對外暴露MyMapManager頭文件件已,在外面調(diào)用的時候使用MyMapManager不用BMKMapManager了笋额。因?yàn)镸yMapManager類繼承自BMKMapManager,所以MyMapManager繼承了BMKMapManager所有的功能篷扩,而且還可以進(jìn)行一些擴(kuò)展和封裝兄猩,簡直再合適不過了。很完美地解決了問題,而且沒有增加多少工作量枢冤。我覺得和之前幾種方案比較鸠姨,這是最完美的一種方案了。現(xiàn)在的方案示意圖如下:


方案四

最后淹真,再附加一個遇到的坑讶迁。

BaiduMapAPI_Map.framework中包含一個資源包,mapapi.bundle需要放到主工程中趟咆,不然會報(bào)錯添瓷。


mapapi.bundle

對外提供的frmework中帶資源包,不解決路徑問題值纱,真是很坑很拉胯鳞贷。報(bào)的莫名其妙的錯誤如下,沒有太多Log信息虐唠,調(diào)試了很久很久才發(fā)現(xiàn)是資源包不對搀愧,浪費(fèi)了很多寶貴的時間。

-[MTLDebugRenderCommandEncoder validateCommonDrawErrors:instanceCount:baseInstance:maxVertexID:]:5161: failed assertion `Draw Errors Validation
renderPipelineState must be set.
'
dyld4 config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/GPUTools.framework/libglInterpose.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib
-[MTLDebugRenderCommandEncoder validateCommonDrawErrors:instanceCount:baseInstance:maxVertexID:]:5161: failed assertion `Draw Errors Validation
renderPipelineState must be set.
'
報(bào)錯
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疆偿,一起剝皮案震驚了整個濱河市咱筛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌杆故,老刑警劉巖迅箩,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異处铛,居然都是意外死亡饲趋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門撤蟆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奕塑,“玉大人,你說我怎么就攤上這事家肯×渑椋” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵讨衣,是天一觀的道長换棚。 經(jīng)常有香客問我,道長反镇,這世上最難降的妖魔是什么圃泡? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮愿险,結(jié)果婚禮上颇蜡,老公的妹妹穿的比我還像新娘价说。我一直安慰自己,他們只是感情好风秤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布鳖目。 她就那樣靜靜地躺著,像睡著了一般缤弦。 火紅的嫁衣襯著肌膚如雪领迈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天碍沐,我揣著相機(jī)與錄音狸捅,去河邊找鬼。 笑死累提,一個胖子當(dāng)著我的面吹牛尘喝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播斋陪,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼朽褪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了无虚?” 一聲冷哼從身側(cè)響起缔赠,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎友题,沒想到半個月后嗤堰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡度宦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年踢匣,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斗埂。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡符糊,死狀恐怖凫海,靈堂內(nèi)的尸體忽然破棺而出呛凶,到底是詐尸還是另有隱情,我是刑警寧澤行贪,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布漾稀,位于F島的核電站,受9級特大地震影響建瘫,放射性物質(zhì)發(fā)生泄漏崭捍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一啰脚、第九天 我趴在偏房一處隱蔽的房頂上張望殷蛇。 院中可真熱鬧实夹,春花似錦、人聲如沸粒梦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽匀们。三九已至缴淋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泄朴,已是汗流浹背重抖。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留祖灰,地道東北人钟沛。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像讹剔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子详民,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容