iOS導(dǎo)出unityFramework歷程

一、背景

由于定義了unity和原生之間交互的橋,因此在導(dǎo)出unity項(xiàng)目后,需要將橋源碼加到unityFramework里面參與編譯,編譯出動(dòng)態(tài)庫(kù)。

image.png
image.png

二、問題及排查歷程

  1. 符號(hào)未定義

在unity那個(gè)demo里面進(jìn)行橋使用:

image.png

發(fā)現(xiàn)符號(hào)未定義的問題:

image.png

然后發(fā)現(xiàn)為什么庫(kù)里面其他的符號(hào)可以被使用:

image.png
  1. 符號(hào)未定義原因

細(xì)看不同之處:

image.png

原來(lái)加了這個(gè)顯示,符號(hào)默認(rèn)對(duì)外界隱藏。查看動(dòng)態(tài)庫(kù)設(shè)置參數(shù),果然如此:

image.png

于是乎我也在自定義的類加上這個(gè)參數(shù)不就解決了?(哈哈哈,只能說(shuō)運(yùn)氣沒有站在我這邊,啪啪打臉):

image.png

在自定義的類聲明前面,也加上了這個(gè)標(biāo)識(shí),再次編譯,wtf還是報(bào)符號(hào)未定義的錯(cuò)誤。然后開始反思為什么會(huì)出現(xiàn)這樣的效果,明明是一樣的。我甚至嘗試把這個(gè)類定義到UnityFramework文件里面,以避免庫(kù)單獨(dú)對(duì)這個(gè)文件做了什么處理。結(jié)果還是不行(依然報(bào)錯(cuò))。然后再次問:明明是一樣的,為什么還會(huì)報(bào)這個(gè)問題????但是真的是一樣的嗎?(使用的時(shí)候還是有不一樣的)請(qǐng)看:

image.png

會(huì)發(fā)現(xiàn),沒有報(bào)錯(cuò)的12行是通過bundle.principalclass去獲取的class,查看靜態(tài)庫(kù)的info.plist可以發(fā)現(xiàn),這個(gè)主要類設(shè)置的就是UnityFramework

image.png

那么至于為什么會(huì)出現(xiàn)符號(hào)未定義的問題也就顯而易見了:因?yàn)檫@個(gè)動(dòng)態(tài)庫(kù)是懶加載的,并不是我們常用的系統(tǒng)自動(dòng)加載的動(dòng)態(tài)庫(kù)。報(bào)符號(hào)未定義的錯(cuò)是因?yàn)樵诰幾g時(shí),如果調(diào)用了[HostRouterApi sharedInstance].sendEventToHostBlock,編譯器會(huì)去驗(yàn)證app的mach-o文件以及它依賴的動(dòng)態(tài)庫(kù)的mach-o文件中是否有這個(gè)類的定義。

由于在編譯時(shí),程序還沒有加載動(dòng)態(tài)庫(kù)UnityFramework,而程序只包含了HostRouterApi類的頭文件,并沒有它對(duì)應(yīng)的.m文件(編譯器只會(huì)將.m文件編譯到最終的mach-o文件中),所以編譯器在app的mach-o文件以及它依賴的動(dòng)態(tài)庫(kù)中找不到HostRouterApi類的定義,然后編譯器就報(bào)錯(cuò)了。所以如果我們把12行換成13行,也會(huì)出現(xiàn)同樣的報(bào)錯(cuò):

image.png

三、究竟設(shè)置了啥,讓這個(gè)demo只能懶加載動(dòng)態(tài)庫(kù)

一開始以為是因?yàn)長(zhǎng)ink Binary With Libraries(構(gòu)建階段(Build Phase),用于指定要與你的應(yīng)用程序一起鏈接的二進(jìn)制文件。而且因?yàn)檎N覀円雈ramework的時(shí)候,這里也會(huì)存在。但是Unity-iPhone這個(gè)demo是沒有的)。

image.png

但是經(jīng)過自己創(chuàng)建新的demo,去驗(yàn)證發(fā)現(xiàn),動(dòng)態(tài)庫(kù)依然會(huì)主動(dòng)被加載,并不需要手動(dòng)去加載(沒有模擬出Unity-iPhone這個(gè)demo的效果)。

這個(gè)問題還有待確定(為什么unity導(dǎo)出來(lái)的demo會(huì)出現(xiàn)使用類編譯找不到符號(hào)的錯(cuò)誤)。。。

四、修復(fù)措施

image.png

新建的類按照這個(gè)方法,讓其符號(hào)是可見的,然后直接導(dǎo)入該動(dòng)態(tài)庫(kù)使用即可。

五、自定義組件

  1. 修改組件名稱

不要直接修改target名稱

image.png

直接修改target名稱雖然可以達(dá)到修改組件名稱的目的,但是后續(xù)unity項(xiàng)目無(wú)法繼續(xù)導(dǎo)出項(xiàng)目(會(huì)因?yàn)槁窂絾栴}導(dǎo)致導(dǎo)出出錯(cuò))。

image.png

修改framework對(duì)應(yīng)target的build settings里面的product name

  1. 更新bridge文件

  2. bridge文件直接放在unityframework參與編譯

bridge文件直接拖進(jìn)unityframework里面參與編譯,有更新的時(shí)候直接替換bridge文件即可。

image.png
  1. unityframework依賴bridge組件

bridge作為一個(gè)單獨(dú)的組件,unityframework依賴該組件:

image.png

注意要把use_frameworks!注釋掉,否則unityframework里面不會(huì)有bridge組件里面的符號(hào)(也就達(dá)不到最終只提供一個(gè)framework給業(yè)務(wù)的目的)。

而且LZAvatarBridge需要支持bitcode(因?yàn)閡nityframework支持)

image.png

但是由于最新蘋果要求關(guān)掉該配置,因此需要把unityframework默認(rèn)的yes改成NO。LZAvatarBridge也不用開啟bitcode。

  1. 自動(dòng)獲取main函數(shù)的兩個(gè)參數(shù)

- (void)runEmbeddedWithArgc:(int)argc argv:(char*[])argv appLaunchOpts:(NSDictionary*)appLaunchOpts

啟動(dòng)unity引擎需要main入口函數(shù)的兩個(gè)參數(shù)(int)argc 和 argv:(char*[])argv,一開始嘗試讓組件使用方在main函數(shù)里面將這兩個(gè)參數(shù)傳給組件。但是細(xì)想一下,發(fā)現(xiàn)這樣不太美觀(主要是即構(gòu)也沒這樣搞,那么肯定是內(nèi)部有辦法去獲取這兩個(gè)參數(shù)的)。經(jīng)過一頓牛逼的操作后,終于實(shí)現(xiàn):

        NSArray<NSString *> *arguments = [[NSProcessInfo processInfo] arguments];
        // 創(chuàng)建一個(gè) char ** 數(shù)組,長(zhǎng)度為 arguments 數(shù)組的長(zhǎng)度加一(用于存儲(chǔ) NULL 結(jié)束符)
        char **argv = (char **)malloc((arguments.count + 1) * sizeof(char *));
        // 遍歷 arguments 數(shù)組,將每個(gè) NSString 對(duì)象轉(zhuǎn)換為對(duì)應(yīng)的 C 字符串
        for (NSInteger i = 0; i < arguments.count; i++) {
            NSString *argument = arguments[i];
            const char *cString = [argument UTF8String];
            // 復(fù)制 C 字符串到動(dòng)態(tài)分配的內(nèi)存中
            argv[i] = strdup(cString);
        }
        // 最后一個(gè)元素設(shè)置為 NULL,表示參數(shù)列表的結(jié)束
        argv[arguments.count] = NULL;
        int argc = (int)arguments.count;
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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