iOS oc與swift組件混編方案

最近因工程業(yè)務(wù)迭代需要實(shí)現(xiàn)oc與swift的工程內(nèi)混編和組件混編踩到了不少的坑,且網(wǎng)上的博客和技術(shù)貼也沒有看到一個(gè)明確的解決方案其絕大部分都是做到一半然后給一個(gè)很耐人尋味的結(jié)果萄涯,所以也是花了大量的時(shí)間去研究過程和原理在這里做一個(gè)簡單的分享與記錄张足,寫的不好室抽,大家請(qǐng)多多指教。

因我的工程是以組件式的形式進(jìn)行迭代開發(fā)的,所以只會(huì)有一個(gè).xcodeproj工程和多個(gè)target的形式進(jìn)行業(yè)務(wù)組件的開發(fā)和剝離膳殷,目前我的每個(gè)業(yè)務(wù)組件并不是一個(gè)龐大的業(yè)務(wù)功能只需要做到每個(gè)組件能夠與Unity引擎之間的通信且能夠完成異步和同步方法交互即可,這樣部署工程目的也主要是為了方便后期可以在一個(gè)工程之中維護(hù)多個(gè)小的組件九火,如果業(yè)務(wù)量龐大的SDK可參考Facebook的開源項(xiàng)目進(jìn)行多工程部署赚窃。oc與swift的混編我先簡單的分為大概四種情況

一册招、工程內(nèi)混編

二、工程依賴組件

三勒极、組件內(nèi)部引用

四是掰、組件外部引用

這里就簡單的說一下每個(gè)混編方案具體該如何實(shí)現(xiàn)。

一辱匿、工程內(nèi)混編

首先在工程內(nèi)混編的話是大家經(jīng)常遇到的一種情況劲装,一般情況在oc工程中第一次創(chuàng)建swift文件驳癌,xcode會(huì)自動(dòng)創(chuàng)建與swift的橋接文件ProjectName-Bridging-Header.h


這個(gè)文件創(chuàng)建出來后即為swift調(diào)用oc文件的header文件,可以將工程內(nèi)用到的所有oc文件引入其中,編譯器則會(huì)將引入的所有oc文件進(jìn)行module化六剥,即在swift的角度而言烛芬,引入的每個(gè)oc文件即為引入的每個(gè)module惶洲,這樣做的目的也主要是為了提高編譯速度劫灶,在編譯的過程中,編譯過的module會(huì)放入一個(gè)編譯好的modules數(shù)據(jù)結(jié)構(gòu)中扔嵌,當(dāng)有重復(fù)的module引入時(shí)限府,dyld會(huì)將先前編譯好的module進(jìn)行l(wèi)ink產(chǎn)生最終的mach-o文件。

如果要在oc中引入swift文件的話痢缎,需要引入在編譯時(shí)才能決議的文件可在Targets -> Build Settings中看到該文件名ProjectName-Swift.h


該文件會(huì)在編譯的過程中產(chǎn)生胁勺,其主要的目的是為了將swift轉(zhuǎn)譯為oc,中間會(huì)有一層hash加密用于防止在LLVM dyld進(jìn)行l(wèi)ink時(shí)出現(xiàn)符號(hào)表沖突独旷。其中的內(nèi)容可在編譯一次后看到署穗,該文件中聲明了工程內(nèi)引入的所有swift文件,其中編譯器在其中的實(shí)現(xiàn)過程就不一一闡述了嵌洼。

二案疲、工程依賴組件

在需要用到swift組件的地方引入ProjectName-Swift.h文件即可

三、組件內(nèi)部引用

3.1 swift調(diào)用oc

在同一個(gè).framework或者.a中實(shí)現(xiàn)swift調(diào)用oc麻养,是無法通過配置Bridging-Header的方式徹底解決褐啡,最終會(huì)在用到組件的地方編譯時(shí)會(huì)出現(xiàn)


看了官方文檔后才知道,如果在同一個(gè)framework中swift想要調(diào)用oc的話鳖昌,需要將該文件引入其umbrella-header.h中备畦,還需要將該target的DEFINES_MODULE配置改為YES即可

3.2 oc調(diào)用swift

只需要將TargetName-Swift.h文件引入即可,但這時(shí)候需要增加命名空間<TargetName/TargetName-Swift.h>

四许昨、組件外部引用

在組件外部調(diào)用的實(shí)現(xiàn)過程中懂盐,我的工程是純oc部署的工程環(huán)境,每個(gè)組件是通過反射進(jìn)行的初始化糕档,在實(shí)現(xiàn)的swift組件的時(shí)候莉恼,無法通過oc的反射方法到純swift的類中(在編譯的過程中swift的類有一層hash加密),所以我做了一層oc的wrapper,讓組件能夠通過oc反射初始化后內(nèi)部再調(diào)用swift

4.1 swift調(diào)用oc

在我的工程環(huán)境中俐银,會(huì)有多個(gè)基礎(chǔ)組件會(huì)在組件之間產(chǎn)生依賴尿背,同級(jí)組件之間可通過基礎(chǔ)組件實(shí)現(xiàn)的中間件進(jìn)行通信。

所以用到的外部組件需要在umbrella-header.h 中將其引入悉患,如果想要公開非組件內(nèi)部的Target需要在Target -> Build Phases -> Headers里面拖拽到Public目錄下残家,如果不想公開則需要拖拽到Project目錄下榆俺,拖到Private目錄下的文件會(huì)在編譯時(shí)產(chǎn)生一個(gè)PrivateHeaders目錄到framework中售躁。具體的區(qū)別可參考官方文檔。


4.2 oc調(diào)用swift

同3.1實(shí)現(xiàn)方案一樣引入即可茴晋。

Tips:

在開發(fā)的過程中可能會(huì)遇到如下問題陪捷,做個(gè)簡單的解決記錄

1.在umbrella-header.h 中引入了非組件內(nèi)部的oc文件會(huì)出現(xiàn)以下警告

Umbrella header for module 'xxx' does not include header 'xxxr.h'是正常現(xiàn)象诺擅,因?yàn)閙odule化的原因市袖,在每個(gè)module之間不應(yīng)該產(chǎn)生引入或者依賴。我這里也暫時(shí)沒有解決這個(gè)警告烁涌,看官方文檔上說需要手動(dòng)配置modulemap文件及引入關(guān)系苍碟,我嘗試了手動(dòng)配置了卻依然不行,有會(huì)編寫modulemap文件的大佬還請(qǐng)說說怎么搞撮执,先在這磕頭了微峰。

2.在我的工程環(huán)境中編譯會(huì)在編譯前3次出現(xiàn)could not build module "xxx",第4次才會(huì)正常的編譯成功抒钱,這也是最離譜的錯(cuò)誤蜓肆,后來才發(fā)現(xiàn)Xcode在編譯的過程中是默認(rèn)開啟了Parallelize Build,會(huì)導(dǎo)致在編譯swift target的時(shí)候無法確定引入關(guān)系導(dǎo)致編譯的不確定性(如果有編譯緩存谋币,則每次都會(huì)成功)


這是加速編譯的配置仗扬,通過關(guān)閉便可以臨時(shí)解決問題讓每次編譯成功,但在Xcode13上蘋果強(qiáng)烈不建議關(guān)閉這個(gè)開關(guān)蕾额,并且更換了title早芭,更加貼切的指明了編譯時(shí)是依賴順序或手動(dòng)順序



所以需要手動(dòng)配置framework的依賴順序后,確保在編譯過程中能先編譯組件依賴的framework后再編譯組件诅蝶,即可正常的完成編譯退个。

3.在發(fā)布組件的時(shí)候需要在podspec文件中添加s.swift_version = "5.0"描述,且可能還會(huì)遇到一個(gè)很離譜的問題就是在高版本Xcode中build的Swift Framework在低版本Xcode中無法正常使用秤涩,會(huì)出現(xiàn)符號(hào)缺失或者符號(hào)未找到等錯(cuò)誤帜乞。具體的原因是因?yàn)槊總€(gè)Framework中嵌入的Swift Module 不一樣,不同版本之間的Swift Module蘋果并沒有做兼容筐眷。所以目前的方案只能在版本相近的Xcode中黎烈,才能使用打出來的Framework。

4.因?yàn)镾DK工程需要進(jìn)行加固,處理包體膨脹要對(duì)其進(jìn)行優(yōu)化需要開啟bitcode 功能又是一堆坑就以后有時(shí)間再寫照棋。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末资溃,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子烈炭,更是在濱河造成了極大的恐慌溶锭,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件符隙,死亡現(xiàn)場(chǎng)離奇詭異趴捅,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)霹疫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門拱绑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人丽蝎,你說我怎么就攤上這事猎拨。” “怎么了屠阻?”我有些...
    開封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵红省,是天一觀的道長。 經(jīng)常有香客問我国觉,道長吧恃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任蛉加,我火速辦了婚禮蚜枢,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘针饥。我一直安慰自己厂抽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開白布丁眼。 她就那樣靜靜地躺著筷凤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪苞七。 梳的紋絲不亂的頭發(fā)上藐守,一...
    開封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音蹂风,去河邊找鬼卢厂。 笑死,一個(gè)胖子當(dāng)著我的面吹牛惠啄,可吹牛的內(nèi)容都是我干的慎恒。 我是一名探鬼主播任内,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼融柬!你這毒婦竟也來了死嗦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤粒氧,失蹤者是張志新(化名)和其女友劉穎越除,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體外盯,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡摘盆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了门怪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骡澈。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡锅纺,死狀恐怖掷空,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情囤锉,我是刑警寧澤坦弟,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站官地,受9級(jí)特大地震影響酿傍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜驱入,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一赤炒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧亏较,春花似錦莺褒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至巡通,卻和暖如春尘执,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宴凉。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來泰國打工誊锭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人弥锄。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓丧靡,卻偏偏與公主長得像签孔,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子窘行,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

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