1. 程式人生 > >【iOS 開發】將自己的框架打包成 Framework 的方法

【iOS 開發】將自己的框架打包成 Framework 的方法

建立 Framework 工程

1. 建立打包工程

  • 開啟 Xcode 新建一個工程,選擇 Framework & Libray 選項中的 Cocoa Touch Framework ,這裡說一下我的 Xcode 版本是 8.3.2
建立工程
  • 因為要打包所需的檔案,所以這裡我自己建立了一個測試類,在實際的打包過程中,直接把需要打包的所有檔案拖到該工程中即可。
測試類

2. 新增公開標頭檔案

  • 選中 Target ,選擇 Build Phases - Headers ,可以看出有三個選項,分別是 Public 、Private 、Project ,把需要公開給別人的 .h 檔案拖到 Public 中,把不想公開的,即為隱藏的 .h
    檔案拖到 Project 中。
Headers
  • 完成上述步驟之後,在預設生成的 .h 檔案中,我的是 TestFramework.h ,把所有需要暴露的 .h 檔案都用 #import <TestFramework/PublicHeader.h>引入,記住一定要將所有需要暴露的 .h 檔案都引入,也就是上面 Headers - Public 中加的所有 .h 檔案,不然編譯後生成的 .framework 在引用的時候會有警告。
引入標頭檔案

3. 更改設定引數

  • 選中 Target ,選擇 Build Settings ,在 Architectures 下增加 armv7s
更改設定引數
  • 選中 Target
    ,選擇 Build Settings ,在搜尋欄搜尋 Mach-O Type ,將 Mach-O Type 修改為 Static Library
更改設定引數

工程打包成 Framework

1. 建立 Aggregate

  • 新建一個 Target ,選擇 Cross-platform - Aggregate ,名字隨便起一個。
建立 Aggregate
  • 選中新建的 Target ,點選 Build Pharas 中的 + ,選擇 New Run Script Phase
New Run Script Phase
  • 點開 Run Script ,新增以下的指令碼程式碼。
# Sets the target folders and the final framework product.
# 如果工程名稱和Framework的Target名稱不一樣的話,要自定義FMKNAME # 例如: FMK_NAME = "MyFramework" FMK_NAME=${PROJECT_NAME} # Install dir will be the final output to the framework. # The following line create it in the root folder of the current project. INSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework # Working dir will be deleted after the framework creation. WRK_DIR=build DEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.framework SIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework # -configuration ${CONFIGURATION} # Clean and Building both architectures. xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphoneos clean build xcodebuild -configuration "Release" -target "${FMK_NAME}" -sdk iphonesimulator clean build # Cleaning the oldest. if [ -d "${INSTALL_DIR}" ] then rm -rf "${INSTALL_DIR}" fi mkdir -p "${INSTALL_DIR}" cp -R "${DEVICE_DIR}/" "${INSTALL_DIR}/" # Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product. lipo -create "${DEVICE_DIR}/${FMK_NAME}" "${SIMULATOR_DIR}/${FMK_NAME}" -output "${INSTALL_DIR}/${FMK_NAME}" rm -r "${WRK_DIR}" open "${INSTALL_DIR}"
Run Script

2. 編譯所有檔案

  • 按照下圖將編譯的 Target 選擇為剛才建立的 AggregateDevice 選擇為 Generic iOS Device ,然後按下 Command + B 開始編譯。
編譯檔案
  • 編譯完成後會自動彈出已經建立完成的 Framework 包內容,最終打包完的 .framework 會在專案下的 Products 資料夾下。
Products

測試打包完的 Framework

  • 新建一個測試工程 TestDemo ,將打包完的 TestFramework.framework 拖到工程中,測試一下剛才建立的 TestClass 類,可以看到資訊打印出來了,測試成功。
測試工程
  • 如果使用打包完的 Framework 有出現崩潰的情況,可以考慮在專案 Other linker flags 中加入一些引數,下面介紹三個常用引數:
-ObjC:加了這個引數後,連結器就會把靜態庫中所有的 Objective-C 類和分類都載入到最後的可執行檔案中。

-all_load:會讓連結器把所有找到的目標檔案都載入到可執行檔案中,但是千萬不要隨便使用這個引數!假如你使用了不止一個靜態庫檔案,然後又使用了這個引數,那麼你很有可能會遇到 ld: duplicate symbol 錯誤,因為不同的庫檔案裡面可能會有相同的目標檔案,所以建議在遇到 -ObjC 失效的情況下使用 -force_load 引數。

-force_load:所做的事情跟 -all_load 其實是一樣的,但是 -force_load 需要指定要進行全部載入的庫檔案的路徑,這樣的話,你就只是完全載入了一個庫檔案,不影響其餘庫檔案的按需載入。

主要步驟大概就是這樣,如果有發現什麼問題可以給我留言,希望能夠幫助大家少走一些坑。

將來的你,一定會感激現在拼命的自己,願自己與讀者的開發之路無限美好。