Cocoapods從1.5.3版本開始起引入Swift靜態庫不再需要在Podfile中添加`use_frameworks!`了。源碼引入Swift庫代碼後生成的Target將會是.a的形式。
下面說一下具體的接入方式。
如果是在Gemfile中指定的pod版本,可以這樣修改:
gem cocoapods, ~> 1.5.3
Pod版本改成1.5版本之後可能會遇到OC頭文件引入報錯的問題。比如有些OC庫中引入AFNetworking的頭文件這樣寫:
#import <AFNetworking.h>
那麼在Pod 1.5.0之後版本就會報錯:`file not found with angled include use quotes instead`, 其實嚴格頭文件引入應該這樣寫:
#import <AFNetworking/AFNetworking.h>
這個錯誤怎樣解決呢?可以在Podfile的post_install鉤子中修改OC庫的header search path, 添加自己依賴的pod的header路徑:
platform = OpenStruct.new(name: :ios) public_headers = installer.sandbox.public_headers.search_paths(platform) installer.pods_project.build_configurations.each do |config| config.build_settings[HEADER_SEARCH_PATHS] = public_headers.join( ) end
pod DEFImageUploader, 0.1.0
import DEFImageUploader
@import DEFImageUploader;
在上面3.2中提到的是以Module的方式import需要使用的Swift庫的。這個前提是Xcode工程的`Enable Module`必須是打開的。
但是我們項目中使用了Ccache這個工具來為項目編譯加速。但是Ccache使用的前提是要把Xcode工程的`Enable Module`設置關閉。這樣一來在OC中就無法使用`@import DEFImageUploader;`的方式來引入Swift庫,要改為`#import <DEFImageUploader/DEFImageUploader-Swift.h>`的方式引入。
2. 挑戰0x2
我們使用`#import <DEFImageUploader/DEFImageUploader-Swift.h>`來引入頭文件後報錯,大意就說`DEFImageUploader-Swift.h`這個橋接頭文件找不到,不論怎麼修改引入方式,比如
#import <DEFImageUploader-Swift.h>
還有
#import "DEFImageUploader-Swift.h"
的引入方式都會報錯。
其實`DEFImageUploader-Swift.h`橋接頭文件已經生成了。
Cocoapods在`DEFImageUploader`的target的Build Phases中自動添加了一個`Copy generated compatibility header`的Script,將`DEFImageUploader-Swift.h`拷貝到了`${BUILT_PRODUCTS_DIR}/Swift Compatibility Header`路徑下。
`Copy generated compatibility header`腳本內容如下:
COMPATIBILITY_HEADER_PATH="${BUILT_PRODUCTS_DIR}/Swift Compatibility Header/${PRODUCT_MODULE_NAME}-Swift.h" MODULE_MAP_PATH="${BUILT_PRODUCTS_DIR}/${PRODUCT_MODULE_NAME}.modulemap"
ditto "${DERIVED_SOURCES_DIR}/${PRODUCT_MODULE_NAME}-Swift.h" "${COMPATIBILITY_HEADER_PATH}" ditto "${PODS_ROOT}/Headers/Public/DEFImageUploader/DEFImageUploader.modulemap" "${MODULE_MAP_PATH}" ditto "${PODS_ROOT}/Headers/Public/DEFImageUploader/DEFImageUploader-umbrella.h" "${BUILT_PRODUCTS_DIR}" printf "
module ${PRODUCT_MODULE_NAME}.Swift { header "${COMPATIBILITY_HEADER_PATH}" requires objc } " >> "${MODULE_MAP_PATH}"
但是`DEFImageUploader-Swift.h`頭文件這麼拷貝的路徑是在`DerivedData`下,在Xcode項目中的Header Search Path中確是"${PODS_ROOT}/Headers/Public"。
這個路徑展開就是在`項目根路徑/Pods/Headers/Public`, 這個路徑明顯跟上面的`${BUILT_PRODUCTS_DIR}/Swift Compatibility Header`不一樣,怪不得會找不到頭文件報錯。
既然問題已經發現了怎麼解決呢? 我的方法是在Podfile中添加一段腳本,讓項目每次編譯後將`DEFImageUploader-Swift.h`從原本的`DerivedData`路徑拷貝到`項目根路徑/Pods/Headers/Public/DEFImageUploader/`路徑下。
這段腳本放在Podfile中的post_install鉤子中,具體代碼如下:
post_install do |installer| installer.pods_project.targets.each do |target| compatibilityPhase = target.build_phases.find { |ph| ph.display_name == Copy generated compatibility header } if compatibilityPhase build_phase = target.new_shell_script_build_phase(Copy Swift Generated Header) build_phase.shell_script = <<-SH.strip_heredoc COMPATIBILITY_HEADER_PATH="${BUILT_PRODUCTS_DIR}/Swift Compatibility Header/${PRODUCT_MODULE_NAME}-Swift.h" ditto "${COMPATIBILITY_HEADER_PATH}" "${PODS_ROOT}/Headers/Public/${PRODUCT_MODULE_NAME}/${PRODUCT_MODULE_NAME}-Swift.h" SH end end end
代碼大意就是做拷貝`-Swift.h`橋接頭文件的事情。
這個腳本會在Pod每次編譯後執行,這樣在項目代碼中引入`#import <DEFImageUploader/DEFImageUploader-Swift.h>`就不會報錯了。