上個(gè)星期,突然有一位做flutter開發(fā)的小伙伴添加了我的微信醇滥,說(shuō)他的項(xiàng)目中報(bào)dyld: Library not loaded: @rpath/App.framework/App這個(gè)錯(cuò)誤审胚,說(shuō)是采用我之前的文章Flutter-module嵌入iOS原生老項(xiàng)目中中的方法可以解決吓揪,但是他們是團(tuán)隊(duì)開發(fā)虎谢,路徑寫死對(duì)多人開發(fā)不夠友好,問我有沒有其他解決方案酬诀。
于是我就打開之前的flutter混合項(xiàng)目脏嚷,開始探索,刪除之前的方法瞒御,開始復(fù)現(xiàn)dyld: Library not loaded: @rpath/App.framework/App這個(gè)錯(cuò)誤父叙,如圖:
其實(shí)項(xiàng)目中報(bào)這個(gè)錯(cuò)誤很常見,這個(gè)錯(cuò)誤就是dyld去加載App.framework/App這個(gè)文件時(shí)沒有找到肴裙,為啥沒有找到呢趾唱,那就是這個(gè)@rpath/App.framework/這個(gè)路徑下沒有App這個(gè)文件唄,首先我們得知道這個(gè)@rpath代表的是啥蜻懦,知道@rpath甜癞,我們就明白了上面這個(gè)報(bào)錯(cuò)的原因。
要知道這個(gè)@rpath是啥宛乃,我們先簡(jiǎn)單了解一下項(xiàng)目編譯到運(yùn)行的過(guò)程中都發(fā)生了什么悠咱?
- 編譯:在我們項(xiàng)目編譯后,會(huì)生成項(xiàng)目的主程序文件(一個(gè)可執(zhí)行文件Executable)征炼,在這個(gè)主程序文件所在的目錄下析既,還有info.plish、_CodeSignature谆奥、Frameworks等文件眼坏,由這些文件組成的一個(gè).app文件,這個(gè)文件再進(jìn)行壓縮就形成了我們熟悉的.ipa文件酸些。(不信你可以把Xcode打包一個(gè)項(xiàng)目宰译,導(dǎo)出ipa包,修改后綴名為.zip魄懂,解壓縮看看??)
-
運(yùn)行:在項(xiàng)目運(yùn)行的時(shí)候沿侈,dyld就會(huì)先加載主程序中所依賴的庫(kù),我們看下主程序中的Load command逢渔,如下圖:
1.png
圖中可以看到肋坚,加載系統(tǒng)的庫(kù),是沒有@rpath的肃廓,因?yàn)橄到y(tǒng)的庫(kù)所在位置是固定的智厌。加載三方庫(kù)如@rpath/AFNetworking.framework/AFNetworking是App.framework和@rpath/App.framework/App的時(shí)候就采用@rpath來(lái)代替路徑,那么@rpath表示的路徑是什么呢盲赊?這個(gè)@rpath是可以設(shè)置的铣鹏,在我們的項(xiàng)目中,如圖:
可看到@rpath是由@executable_path/Frameworks表示的哀蘑,那么這個(gè)@executable_path又是什么呢诚卸?它是系統(tǒng)為了方便表示主程序這個(gè)可執(zhí)行文件所在的路徑而設(shè)計(jì)的一個(gè)變量葵第,@executable_path表示的是主程序這個(gè)可執(zhí)行文件所在的路徑。那么@executable_path/Frameworks也就是@rpath則代表的是主程序文件所在的路徑下Frameworks這個(gè)文件夾合溺。
搞清楚@rpath是什么這個(gè)問題了卒密,那么我們?cè)賮?lái)看一下.app/Frameworks都有什么?
發(fā)現(xiàn)其中確實(shí)沒有App.framework棠赛。
我當(dāng)時(shí)想到的第一種解決方案就是找到flutter_module中的App.framework哮奇,然后將它c(diǎn)opy到編譯后的.app/Frameworks下,不就解決了嗎睛约?編譯后手動(dòng)copy也行鼎俘,當(dāng)然如果項(xiàng)目clean了,就沒有了辩涝。我這里采用腳本copy贸伐,如圖,在Build Phases中新建一個(gè)Run Script怔揩,將腳本寫入即可捉邢。
經(jīng)過(guò)一番操作,我這里項(xiàng)目可以順利運(yùn)行了商膊,但是這個(gè)方式給到咨詢我的那個(gè)小伙伴歌逢,他那里的項(xiàng)目卻不行,編譯都不過(guò)翘狱。
然后又經(jīng)過(guò)一系列的查找,最終我把問題定位到flutter的SDK的版本上砰苍,因?yàn)楣俜教峁┑膄lutter_module嵌入iOS原生項(xiàng)目中第一種方式(pod導(dǎo)入)潦匈,實(shí)際上是使用了podhelper.rb這個(gè)腳本來(lái)完成一系列的加載,我查看了這個(gè)腳本的位置是在flutter的SDK中的赚导,當(dāng)時(shí)想到一個(gè)問題就是:我的這個(gè)項(xiàng)目21年9月份嵌入的的茬缩,我的flutter版本2.2.3也不是最新的,這位咨詢的小伙伴的flutter版本也不是最新的吼旧,于是凰锡,我讓他升級(jí)一下flutter版本看下,果不其然圈暗,他升級(jí)flutter后就可以順利運(yùn)行了掂为。
其他同學(xué)如果遇到這個(gè)問題,可以先嘗試一下flutter的版本升級(jí)员串,少走一些彎路勇哗。
最后貼出解決辦法:(評(píng)論區(qū)小伙伴 ningcol 給出的方法,在此感謝寸齐!)
重裝Cocoapods和ruby-macho:
sudo gem uninstall ruby-macho
sudo gem uninstall cocoapods
sudo gem install ruby-macho
sudo gem install cocoapods