<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
Flutter 在 iOS 上的編譯問題相信大家多多少少遇到過,不知道大家在搜尋這方便的問題時,得到的答案是不是讓你 clean 或者 install 多幾次,很多時候就算解決完問題,也是處於薛定諤的狀態,所以本篇也簡單記錄下 Flutter 開發中,OC 混編 Swift 遭遇動態庫和靜態庫的問題,希望對“蒙圈”中的你有點幫助。
首先,當我在一個 OC 專案裡接入一個 Swift 外掛,可能會遇到什麼問題?
如下圖所示,如果你是一個比較老的 Flutter 專案,那可能會出現 swift 外掛出現 not found 的問題。
針對這個問題,一般都是建議在 Podfile 檔案下新增 use_frameworks!
,有時候還會建議新增 use_modular_headers!
,那這兩個標記位的作用是什麼?
target 'Runner' do use_frameworks! use_modular_headers! flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) end
我們知道 Podfile 的作用是處理 CocoaPads ,而 use_frameworks!
告訴 CocoaPods 你想使用 Framework 而不是靜態庫,而預設由於 Swift 不支援靜態庫,因此有一開始 Swift 必須使用 Framework 的限制。
靜態庫和 Framework 的區別在於:
另外一個設定 use_modular_headers!
,它主要是將 pods 轉為 Modular,因為 Modular 是可以直接在 Swift中 import ,所以不需要再經過 bridging-header 的橋接。
但是開啟 use_modular_headers!
之後,會使用更嚴格的 header 搜尋路徑,開啟後 pod 會啟用更嚴格的搜尋路徑和生成模組對映,歷史專案可能會出現重複參照等問題,因為在一些老專案裡 CocoaPods 是利用Header Search Paths 來完成引入編譯,當然使用 use_modular_headers!
可以提高載入效能和減少體積。
繼續回到問題上,我們在新增完 use_frameworks!
之後,有一定機率中獎各種 Undefined symbol 的錯誤問題,這時候不要慌,因為這是 Swfit 裡有靜態庫導致。
很明顯 Swift 不支援靜態庫的行為不科學,所以從 Xcode 9 開始 Swift 就開始支援靜態庫,而 CocoaPods 1.9.0 開始,引入了 use_frameworks! :linkage => :static
來生支援有靜態庫和 Framework 的情況。
所以修改 use_frameworks 設定,增加 static 之後可以看到 Undefined symbol 的錯誤都消失了,但是執行之後,可能會喜提新的問題: non-modular header 。
如果你去搜尋答案,有很多答案會告訴你如下圖所示,通過 Allow Non-modular Includes in Framework Modules
設定為 true
就可以解決問題,但是很明顯這並不是正解,它更多適用於臨時的緊急狀體下。
當然,你也可以在出現問題的外掛的 .podspec
下單獨設定 ALLOW ,效果相同,更輕量級,但是這也只是臨時解決方案。
s.user_target_xcconfig = { 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES' }
為什麼說這種方式不靠譜,因為你不知道官方會什麼時候刪除這種允許,當然這個問題網友提供的解決方案其實千奇百怪:
#import "MyFile.h"
而不是 #import <MyFramework/MyFile.h>
;#import
語句移到 .m
(而不是將其放在.h
標頭檔案中), 這樣它就不會有包含 non-modular header 的問題,例如: github.com/AFNetworkin… ;#import <FrameworkName/Header.h>
有可能它們都能解決你的問題,但是為什麼呢?下次遇到這些問題要選哪個解決?
迴歸到我們的問題,其實我的問題關鍵是:不能在 Framework Module 中使用非 Modular 的 Header,也就問題是在 Framework Module 中載入了非當前 Module 的標頭檔案,而由於 Header 是對外 public ,比如設定到了 s.public_header_files
,就會導致非 Modular 的 Header 也出現對外暴露的風險,所以我這邊的解放方式也很簡單:
*在 s.public_header_files
裡只放需要公開的 Plugin.h ,使用了非 Modular 的 Header 不對外 public,從而符合規範達到編譯成功。
所以這裡面的核心是:不要在 Umbrella Header File 中參照不需要對外公開的 OC 標頭檔案去作為子 module ,這也解釋了為什麼上面講出問題的 #import
語句移到 .m
就解決問題的邏輯。
例如有時候你還會參照一些系統的 C Module ,其實在 Framework Module 化過程中也會有類似的問題。
所以知道了為什麼和怎麼解決,就不會只是粗暴通過 LLVM 的設定來設定 Allow Non-modular Includes in Framework Modules
去解決薛定諤的問題。
另外你可能還有用到的,比如模擬器編譯提示 unsupport arm64、 BITCODE 失敗,SWIFT_VERSION 版本衝突等等:
post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) target.build_configurations.each do |config| # building for iOS Simulator, but linking in an object file built for iOS, for architecture ‘arm64' config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64' #不支援 BITCODE config.build_settings['ENABLE_BITCODE'] = 'NO' #解決swift模組問題 config.build_settings['SWIFT_VERSION'] = '5.0' end end end
當然,最後一句話:珍愛頭髮,遠離 Swift 混編。
以上就是Flutter iOS開發OC混編Swift動態庫和靜態庫問題填坑的詳細內容,更多關於Flutter iOS OC混編Swift的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45