簡述iOS開發framework製作與使用

weixin_34019929發表於2017-05-14

前言

  • 我的第一次,請多多指教!目的是給予有需要的朋友以及方便自己日後的查閱。

iOS開發庫檔案的分類

靜態庫:

    1. 靜態庫有 .a 和 .framework 兩種形式;
    1. 在程式編譯時會被連結到目的碼中,程式執行時將不再需要改靜態庫。

動態庫:

    1. .dylib 和 .framework 形式,後來.dylib動態庫又被蘋果替換成.tbd的形式;
    1. 在程式編譯時並不會被連結到目的碼中,只是在程式執行時才被載入,因為在程式執行期間還需要動態庫的存在。

結論

  • 同一個靜態庫在不同程式中使用時,每一個程式中都得匯入一次,打包時也被打包進去,形成一個程式;
  • 而動態庫在不同程式中,打包時並沒有被打包進去,只在程式執行使用時,才連結載入(如系統的框架如 UIKit、Foundation 等),所以程式體積會小很多,但是蘋果不讓使用自己的動態庫,否則稽核就無法通過(為什麼不讓使用本人不是很清楚,還請大神普及)。

framework 製作過程

1. 首先新建一個專案,選擇 Cocoa touch Framework :

2782021-bd2c8cc2e533c3e0
新建CocoaTouchFramework

2. 然後隨便取一個名字 MyFramework_Create:

2782021-1824a675103e9134
取名MyFramework_Create

3. 然後根據不能的業務需求寫好自己的程式碼,這裡因為是測試,我隨便寫點,新建一個 Dog 類,然後公開一個方法並隨便 log 一點東西:

2782021-fca2baf80f096253
新建Dog類

4. 工程配置:

  • 4.1 選擇工程檔案 > target 第一項 > Build Setting > 搜尋 linking,然後幾個需要設定的選項都顯現出來,首先是 Dead Code Stripping 設定為 NO,網上對此項的解釋如下,意思是如果開啟此項就會對程式碼中的 " dead ”、" unreachable ” 的程式碼過濾,不過這個開關是否關閉,似乎沒有多大影響,不過為了完整還原 framework 中的程式碼,將此項關閉也未曾不可。

    • The resulting executable will not include any “dead” or unreachable code.
  • 4.2 然後將Link With Standard Libraries關閉,我想可能是為了避免重複連結:

  • 4.3 最後將 Mach-O Type 設為 Static Library,framework 可以是動態庫也可以是靜態庫,對於系統的framework 是動態庫,而使用者製作的 framework 只能是靜態庫.


    2782021-8ed7827c66b31549
    工程配置

5. 標頭檔案的設定:將需要公開的標頭檔案從 Project 中拖入 Public,至於是否需要將私有的標頭檔案拖入Private,我覺得直接放在 Project 中即可,若是 Private 中有標頭檔案,打包以後的 framework 中會多出一個Private 的資料夾包含著放入 Private 的標頭檔案,不過我覺得如果是私有最好還是不要讓別人看到。以下有三種設定方法,設定前需要在 .h 檔案匯入:

2782021-9ac8072f71d335ac
標頭檔案的設定
  • 5.1 在 target 下找到 Build Phases, 點開 Headers 看到 Project 下面的檔案直接右鍵就可以看到一些選項,選擇你所需 Public 的即可。


    2782021-5372c1700aec88b2
    標頭檔案的設定1
  • 5.2 在上面的 Headers 介面的時候直接將 Project 下面的檔案拖到 Public 下面即可。


    2782021-6c4721d8c1337813
    標頭檔案的設定2
  • 5.3 選中 Dog.h 檔案,在 Xcode 右邊找到 Target Memership 右下角的(注意不是 Xcode 整個介面右下角)上下箭頭,那裡就有你想要的:


    2782021-feb8fac6a1a0b1d4
    標頭檔案的設定3

6. iPhone 5 和 iPhone 5c 特殊機型架構的支援配置

  • 選中 Build Settings > Architectures > 單擊該選項的右邊 > other > armv7s ,即可


    2782021-afb071eb4cfb458a
    特殊機型架構的支援配置1

    2782021-4caf30cba04c25c6
    特殊機型架構的支援配置2

7. 編譯生成 .framework 檔案

  • 7.1 先選擇Generic iOS Device,按下 Command+B:Build 一下:
2782021-b3544b45b147e8d4.png
真機編譯.png
  • 7.2 然後隨意選擇一個模擬器再次 Build 一下:
2782021-27d270bb4d27da5b.png
模擬器編譯.png

8. 合併真機與模擬器生成 .framework 檔案:

  • 8.1 Show in Finder 找到 Build 後的 framework
2782021-dc7bf9cc645237dd.png
Show in Finder.png
  • 8.2 我們看到總共有兩個資料夾,上面是真機編譯生成的檔案,下面是模擬器編譯生成的檔案。
2782021-224e578161381e33.png
真機與模擬器的framework.png
  • 8.3 我們在 Products 同級目錄下(路徑可以任意選)新建一個 名為 MyFramework_Create 的資料夾作為輸出路徑,這裡取名要與專案名一致,至於為什麼到後面自己會明白的。
2782021-c33b7fccdd5937ad.png
新建MyFramework_Create的資料夾作.png
  • 8.4 使用命令列合併:lipo -create + 上面兩個檔案的路徑(是指真機與模擬器MyFramework_Create.framework 目錄下的 MyFramework_Create檔案) + -output + 合成後檔案的輸出路徑。 最後回車即可。


    2782021-d2870c6871fc55a7
    命令列合併
  • 8.5 將生成的 MyFramework_Test.lipo 檔案刪除字尾名並代替真機下的 MyFramework_Test 檔案就完成了。


    2782021-144ce8652b2b5d83
    代替MyFramework_Create

framework的測試

1. 新建名為 MyFramework_Test 的工程,注意選擇的是 Single View Application :

![](file:////Users/dinpay/Desktop/MyFramework_Create/新建SingleViewApplication.png)
![](file:////Users/dinpay/Desktop/MyFramework_Create/新建MyFramework_Test.png)

2782021-4fd5b399fb97a286.png
新建MyFramework_Test.png

2782021-bacbfb9715af2f7c
新建SingleViewApplication

2. 將所需要的標頭檔案匯入工程,新建一個 dog 物件,並呼叫 doSmothing 方法,檢視控制檯的輸出,現在已經成功匯入測試完成:

2782021-f58f06ec8e394c10
執行結果

經典報錯

1. 缺少相關標頭檔案的路徑,在有些部落格上看到說在測試之前就要匯入 framework 的 Headers 的路徑,發現這不完全正確,在我的經驗中如果 framework 中引入了第三方不匯入會報錯,沒有引用的就沒有報錯,所以個人認為還是看情況,如果執行起來報錯說找不到標頭檔案的話,那再做相關配置也無妨,配置方法如下:

![](file:////Users/dinpay/Desktop/MyFramework_Create/標頭檔案配置.png)

2782021-f1149841c7a8ed27.png
標頭檔案配置.png

2. 缺少相關裝置架構,報錯如下:

2782021-757181a3b8bac83c
缺少相關裝置架構
  • 2.1 庫中缺少了i386架構的檔案,這時我就比較困惑了,明明將模擬器生成的庫檔案合併進來了,怎麼在模擬器上編不通呢!用 lipo -info 命令檢視一下,果然沒有i386架構的檔案
    ![](file:////Users/dinpay/Desktop/MyFramework_Create/架構前.png)
2782021-b0ed25d6fd10cbe9.png
架構前.png
  • 2.2 重新選擇 iPhone 5 模擬器與 iPhone 7 模擬器兩者執行生成的 .framework 檔案合併後與真機生成的 .framework 檔案再次合併檢視資訊,果然有了


    2782021-49109e25342a7c70
    架構後
  • 2.3 架構總結:

    • 對於模擬器來說 4s 和5的模架構是 i386 的32位架構,5s 至今是 x86_64 的64位架構。對於真機來說 3GS~4s 是 armv7 架構,5 和 5c 是 armv7s 架構,5s 至今是 arm64 架構。

3. 將下圖中的選項設為 YES,導致其編譯時只生成當前機器的框架,將其設定為 NO 後,發現用模擬器編譯後生成的 framework 同時包含 x86_64 和 i386 架構。

2782021-6dad805010058cd8

4. 在專案中引入靜態庫後,archive 的時候會出現錯誤

2782021-4ba676251f566223
  • 解決辦法:


    2782021-563b75bd66ad1405

    2782021-9cc73a888e71b7db
    MacDown logo
  • Bitcode 是蘋果在 Xcode7 及以後推出的新功能。用於程式碼的二次編譯,針對 CPU 進行優化,編譯工作由蘋果 AppStore 後臺來完成。針對 iOS 是可選項,預設開啟。watchOS 和 tvOS 是必選項,所以需要開啟庫工程的此選項並加上 -fembed-bitcode 引數,重新編譯。

相關文章