記一次在Tweak中引入Swift framework的過程

最近想在一個插件裏打通App和web端,實現通過web控制App,方案是選用socket.io作爲服務端和web前端。iOS端socket.io是一個純swift實現的庫。目前Theos對swift的支持還不是很完善,但是可以完成一般的工作了。Theos現在是支持swift文件編譯的。

首先我們要來看一下theos倉庫中對swift支持的一些介紹。其中Swift Runtime這部分比較關鍵的,需要按照這裏的說明修改control文件。接下去是OC和Swift交互,這部分跟我們平常開發是相同的,你可以在Makefile裏指定橋接文件等,最後說現在還不能用swift寫tweak,嗯,你只能寫非hock的代碼。很久前就有人在問【已解決】如何使用 Theos 編譯 Swift 源文件

我的需求是引入一個swift framework,我的工程本身不依賴libswift*.dylb,但是我依賴的庫依賴它們,因此我也需要引入swift runtime。

在tweak裏引入framework的話,可以參考這些資料Tweak如何導入第三方framework怎麼在Tweak加入第三方framework如何在Theos工程裏嵌入第三方SDK或者靜態庫。相對而言,我個人比較喜歡Tweak 工程創建、配置教程 & 實現logos語法自動補全裏的說明。簡而言之,就是我們需要把framework通過layout來放到越獄的系統裏。因爲framework不在宿主bundle裏,也沒有被寫入宿主macho文件的load command裏。因此如果framework的install name base是@rpath,那麼即使dylib通過insert libraries被加載了,dylib依賴的framework也無法被找到。

可以通過otool工具查看macho文件依賴的庫及其加載路徑。

otool -L .../dylib
otool -L .../xx.framework/xxx

要修改具體的路徑的話,要使用install_name_tool。install_name_tool的主要用法有兩種:
install_name_tool -id [path] [target]是用來修改該庫被引用的路徑,相當於是一個自己的屬性。如果某個庫可能會被多個目標引用,那麼修改該庫的id比較方便。如果只是修改某個庫裏的某個依賴庫的路徑,可以用install_name_tool -change [oldpath] [newpath] [target]

我們先要修改從其他工程編譯產生的framework的id,然後由於這兩個庫存在引用關係,因此也要修正被引用的庫的路徑。這樣,我們的庫就處理妥當了,把它放到layout下你想要放置framework的地方。修改Makefile,引入這兩個庫。如果我們的項目裏沒有swift文件,我們現在編譯是可以通過的。但是這裏有個問題,我們的tweak動態庫不會被加載。這個問題目前還沒想通,需要繼續研究下。如果你引入一個swift文件,再編譯的話,你會發現dylib裏多了一條libswiftCore.dylib的依賴,那麼這個時候,這個動態庫會被加載。

對於Xcode高版本,swift 5.0的路徑和theos當前版本不一致,導致一些庫不會被鏈接。相關提及該問題的話題:unable to compile swift tool using XCode 11 #476This copy of libswiftCore.dylib requires an OS version prior to 12.2.0 [create_patched_sdk] Update bash script, create new python script #31

如果你使用的是DH開發的老版本theos的話,dpkg-deb存在問題,在解壓拷貝framework到指定路徑時會出現錯誤,路徑會發生錯亂,導致提示路徑不存在。在嘗試若干次make package之後會成功,但是有時候在Cydia裏查看包內容,發現無法查看,打開文件列表的plist文件時,發現有些路徑出錯了。遷移到新版theos,升級dpkg-deb之後,這個問題就沒出現了。可能跟改成了lzma歸檔方式有關,具體暫不細究,可以查看issue追蹤問題的發現和解決。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章