Xcode 工程新增 “動態” Framework 的幾種方式
在上一條小集,我們分別介紹了 “.a 靜態庫”、“靜態 framework” 和 “動態 framework” 的異同。
接下來我們將介紹一下,如何在 Xcode 工程中新增動態庫(Dynamic Library)。
首先我們知道,對於 “.a 靜態庫” 和 “靜態 framework”,直接把相關檔案拖拽到工程中,並勾選 Copy if needed 選項即可,無需其它額外的設定;
而對於新增“動態 framework”,稍微比較麻煩,主要有以下幾種方式。
PS:我們這裡說的“新增動態庫”是指第三方動態庫,而不是像 UIKit.framework、Foundation.framework 或者 libc++ 等系統自帶的動態庫,對於它們的依賴新增很簡單,直接在 General -> Linked Frameworks and Libraries 中點選加號搜尋新增即可。
手動方式
在 Xcode 工程中選中 app 對應的 target,然後在 General -> Embedded Binaries 下點選加號,如圖 1,在彈出的視窗選擇 Add Other…,最後在 Finder 中選擇你要新增的“動態 framework”,並勾選 Copy if needed 即可。需要注意的是,你不能直接在 Finder 中把 .framework 檔案拖拽到 Embedded Binaries 中,否則會報錯。
關於手動新增動態庫的更多細節以及遇到問題的解決辦法,可參考蘋果官方的教程: ofollow,noindex">《Embedding Frameworks In An App》
但是!這種方式看似很方便,其實有個坑是:我們上一條小集提到,一般動態二進位制檔案都會包含很多處理器架構,例如:i386, x86_64, armv7, armv7s, arm64 等,然後 Xcode 在編譯連結時,對動態二進位制檔案是直接拷貝到 .ipa 包中,並不會像連結靜態庫那樣篩選掉未用到 architecture,而蘋果又不允許把包含 i386, x86_64 等模擬器架構的包上傳到 App Store Connect 後臺,會報錯。因此,我們在打 Release 正式包時往往需要手動通過 lipo 命令或者編寫指令碼移除掉這些 Invalid Architectures。(除非你的開發工程只通過真機來除錯,不準備在模擬器裡執行,且新增的動態庫剛好又不包含 i386、x86_64)
使用 Carthage 整合
對於通過 Carthage 整合的第三方庫,在 Cartfile 檔案中新增好依賴後,然後執行 carthage update
命令會幫我們生成一個個“動態 framework”,例如 AFNetworking.framework、SDWebImage.framework 等,然後把它們拖拽到工程中的 General -> Linked Frameworks and Libraries ,然後在配置相關拷貝指令碼和命令,詳細可參考 Carthage 的 Quick Start 教程。
這裡有個關鍵操作是,需要在 Xcode 工程的 Build Phases 中新增一個執行指令碼(New Run Script Phase),並在指令碼中執行如下命令:
/usr/local/bin/carthage copy-frameworks
如圖 2 所示:
該命令的作用大概就是,在打包拷貝動態庫時自動幫我們移除掉其中的 i386、x86_64。
使用 CocoaPods/">CocoaPods 整合
同樣地,通過 CocoaPods 整合動態庫時,也會在工程中自動幫我們新增一個 Shell 指令碼用於做這件事,如圖 3 中的 [CP] Embed Pods Frameworks,
大家可以自行查閱該 Pods-xxx-frameworks.sh 指令碼的內容,裡面有個函式 strip_invalid_archs()
就是用於在打包時移除無用的處理器架構,如圖 4:
因此,我們可以把自己開發的或者他人提供的動態 framework,通過 CocoaPods 來整合到工程中:建立一個 Pods 私有 git 庫(相信大家已經很熟悉了),在 git 庫中新增相關動態 .frameworks 檔案,然後其 Podspec 檔案的寫法大致如圖 5 所示,最後在你的工程中 pod install
即可。
最後我們思考一個問題:“靜態 framework” 和 “動態 framework” 在使用上似乎也沒什麼不同,而工程新增 “動態 framework” 又比較繁瑣,那麼在 iOS/macOS 開發中什麼情況下會使用動態庫呢?