1. 程式人生 > >iOS 靜態庫製作(Xcode9.0 版本)(注:親測.a靜態檔案放在Unity Plugins/IOS 也可用)

iOS 靜態庫製作(Xcode9.0 版本)(注:親測.a靜態檔案放在Unity Plugins/IOS 也可用)

在實際開發過程中,我們或許會涉及到各種不同的協作開發形式,或許也有將自己封裝的類運用到其它 app 的情況,在這個時候,如果單純的使用 crtl+c、ctrl+v ,或許使得專案變得不容易維護,整潔性,還有封裝性大大降低,這個時候,我們需要庫的支援。

基本知識:

1. 庫類別

  • 靜態庫(.a 和.framework)
  • 動態庫(.liby和.framework)

2.靜態庫和動態庫的區別

2.1靜態庫

  • 平時我們用的第三方SDK基本上都是靜態庫。
  • 靜態庫在專案編譯時完整地拷貝至可執行檔案中,被多次使用就有多份冗餘拷貝。
  • 靜態庫很大的一個優點是減少耦合性,因為靜態庫中是不可以包含其他靜態庫的,使用的時候要另外匯入它的依賴庫,最大限度的保證了每一個靜態庫都是獨立的,不會重複引用。
  • 靜態庫有.a 和 .framework兩種形式。

2.2動態庫

  • iOS平時使用的系統庫基本是動態庫,比如使用頻率最高的UIKit.framework和Fundation.framework。
  • 動態庫在程式執行時由系統動態載入到記憶體,供程式呼叫,系統只加載一次,多個程式共用,節省記憶體。
  • 動態庫在製作的時候可以直接包含靜態庫,也能自動link所需要的依賴庫。
  • 動態庫有.dylib/.tbd 、.framework兩種形式。
  • 蘋果禁止iOS開發中使用動態庫

3.版本

  • 真機-Debug版本
  • 真機-Release版本
  • 模擬器-Debug版本
  • 模擬器-Release版本

3.1 Debug

  • 含完整的符號資訊,以方便除錯
  • 不會對程式碼進行優化

3.2 Release

  • 不會包含完整的符號資訊
  • 的執行程式碼是進行過優化的
  • 的大小會比Debug版本的略小
  • 在執行速度方面,Release版本會更快些(但不意味著會有顯著的提升)

基本操作:.a靜態庫製作

1. 新建靜態庫工程

Create a New Xcode project -> Framework&Library -> Cocoa Touch Static Library 
這裡寫圖片描述

檔案結構如下:

這裡寫圖片描述

2. 配置工程環境

2.1配置最低支援版本

這裡寫圖片描述

2.2設定適配所有模擬器架構重要

project -> buildSeting -> Build Active Architecture Only 設為NO

這裡寫圖片描述

3. 新建的檔案

3.1新建方法



3.2新增公開檔案

3.2.1 點選“+” 新增”Header Phase”

這裡寫圖片描述

3.2.2 新增檔案到 project

這裡寫圖片描述

3.2.3 拖拽.h到 public

這裡寫圖片描述

最終結果如下:

這裡寫圖片描述

4. 生成.a檔案

此處注意需要生成4個

4.1修改環境

這裡寫圖片描述

這裡可以選擇 Debug 和 Release 環境

這裡寫圖片描述

4.2選擇模擬器+Debug 環境+“cmd+R”(即是執行 三角形)生成.a

這裡寫圖片描述

此處注意需要生成4個 
如此類推打出四種.a

  • 真機-Debug版本
  • 真機-Release版本
  • 模擬器-Debug版本
  • 模擬器-Release版本 

最終生成結果 
這裡寫圖片描述

4.3合併 debug 兩個包和 release 兩個包

注意:這裡的合併指的是 1.debug 下真機+模擬器合併 2.release 下真機+模擬器合併 

4.3.1將4個.a檔案拷貝到單獨資料夾

這裡寫圖片描述

4.3.2 合併

開啟終端 
命令規則

  • 1
  • 2
  • 3
  • 4

這裡寫圖片描述

標註出是自己起名

同理 release 也是如此 最後生成兩個檔案

這裡寫圖片描述

5.使用方法

5.1新建一個新工程 
**5.2引入檔案 
5.2.1引入libStaticWork-Debug.a和libStaticWork-Release.a

5.2.2引入 include 檔案 
在之前的靜態庫檔案找到任意的生成檔案 引入 include 檔案

這裡寫圖片描述

最後引入結果如下

5.3呼叫以及結果

這裡寫圖片描述

基本操作:.framework靜態庫製作

1.新建 framework 工程

這裡寫圖片描述

2.新建檔案類

這裡寫圖片描述

3.修改工程檔案配置

build setting ->搜尋 mach -> 修改 mach -O Type ->static Library

這裡寫圖片描述

這裡寫圖片描述

4.引入其他第三方庫(如果有的話)

⚠️注意:匯入第三方靜態庫的時候不要選擇新增到target中

這裡寫圖片描述

5.暴露標頭檔案

拖拽檔案到這裡

這裡寫圖片描述

6.生成 .framework

6.1修改環境

這裡寫圖片描述

這裡可以選擇 Debug 和 Release 環境

這裡寫圖片描述

6.2選擇模擬器+Debug 環境+“cmd+R”(就是點選 執行 三角形)生成.a

這裡寫圖片描述

此處注意需要生成4個 
如此類推打出四種.a

  • 真機-Debug版本
  • 真機-Release版本
  • 模擬器-Debug版本
  • 模擬器-Release版本 

最終生成結果(可以右鍵在 Finder 檔案中檢視)

這裡寫圖片描述

7.合併 debug 兩個包和 release 兩個包

注意:這裡的合併指的是 1.debug 下真機+模擬器合併 2.release 下真機+模擬器合併 

7.1將4個.a檔案拷貝到單獨資料夾

這裡寫圖片描述

7.2 合併

開啟終端 

命令規則

lipo -create 多個需要合併的.a靜態檔案 -output 輸出到目標路徑的打包的靜態檔案

示例:

lipo -create Desktop/a/libMyStaticLibRelease-iphonesimulator.a Desktop/a/libMyStaticLibRelease-iphoneos.a -output Desktop/a/libMyStaticLib-Release.a


這裡寫圖片描述

(報錯:

xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

解決方法

解決方法很簡單,就是在命令列中執行 xcode-select --install ,然後會啟動下載並安裝Command line tools OS X 10.11) for Xcode,注意,這個命令並不會下載完整的Xcode,但是下載依然會很慢

標註出是自己起名

同理 release 也是如此 最後生成兩個檔案

這裡寫圖片描述

(此處把生成的靜態檔案放在Unity Assets下新建的 Plugins/iOS資料夾下,也可呼叫

呼叫方法程式碼如下:


**7.3替換檔案 
7.3.1尋找之前生成的 任意framework 
**7.3.2替換二進位制檔案

替換前

這裡寫圖片描述

替換後

這裡寫圖片描述

8.使用方法 
8.1新建工程 
8.2應用 framework 
8.3結果如下

這裡寫圖片描述

9.注意的地方

9.1警告 
如果我們什麼都不配置的話 應用 framework 裡面的檔案 會產生如下的警告 
missing submodule ‘StaticFramework.framewokrTool”

這裡寫圖片描述

解決方案: 
在 framework 的標頭檔案也就是建立 framework 時同名的.h裡面引入我們的標頭檔案

這裡寫圖片描述

就可以了

9.2資原始檔 .bundle

靜態庫中有使用到圖片、音視訊等資原始檔,可以將這些檔案打包成.bundle檔案供靜態庫使用。

最簡單的方法是,新建一個資料夾,將圖片、音視訊等資源拖到資料夾中,將資料夾字尾名改為.bundle. 
靜態庫想要使用裡面的資源的話需要先獲取到該.bundle檔案。

  • 1

靜態庫中使用.bundle檔案裡面的圖片的方法是:

  • 1
  • 2

⚠️注意:.bundle檔案無法封裝到framework裡,需要將.framework,.bundle同時匯入專案中才能正常使用

9.3使用category

在製作framework的時候,如果使用了category,則使用該framework的專案執行時會crash,此時需要在該工程中 other linker flags新增一個引數 -ObjC

這裡寫圖片描述

引數說明

  • ObjC:加了這個引數後,連結器就會把靜態庫中所有的Objective-C類和分類都載入到最後的可執行檔案中

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

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

    本文轉自:https://blog.csdn.net/wanna_dance/article/details/78687676