iOS開發中靜態庫之".framework靜態庫"的制作及使用篇
- .framework靜態庫支持OC和swift
.a靜態庫如何制作可參照上一篇: iOS開發中靜態庫之".a靜態庫"的制作及使用篇
一.OC創建.framework靜態庫
1.創建工程,語言選擇OC
2.進入工程后,會自動幫我們創建一個.h文件,主頭文件,和我們項目名稱一般完全一致.不要刪除了!
3.編寫核心代碼
- 依舊使用簡單示例,MathTools
MathTools.h文件
@interface MathTools : NSObject
+ (NSInteger)sumNum1:(NSInteger)num1 num2:(NSInteger)num2;
@end
MathTools.m文件
@implementation MathTools
+ (NSInteger)sumNum1:(NSInteger)num1 num2:(NSInteger)num2
{
return num1 + num2;
}
@end
4.制作.framework靜態庫
cmd + B 編譯一下- 我們就會發現在Products文件下面有個實體的.framework文件
- 右鍵
Show In Finder - 發現文件夾內有個.h頭文件,但它是主頭文件,並不是我們想暴露出去的頭文件,我們想暴露的頭文件是MathTools.h
- 來到項目配置,把MathTools.h文件暴露出去

- 把MathTools.h拖到Public之后,cmd + B編譯一下
Show In Finder,發現Headers文件夾內有兩個.h文件了,我們要暴露的.h文件也在內- 大家可能還會發現一個exec的文件,它其實就是我們的.m文件被編譯之后的二進制文件
5.測試.framework靜態庫,先使用OC創建測試工程
-
將我們制作好的.framework靜態庫拖入測試的工程項目中
-
假如我們用OC創建的測試工程
-
在ViewController中執行touchBegan方法,點擊控制器獲取結果
- 在ViewController.m文件中導入靜態庫的主頭文件
#import <MTYMathToolsOC/MTYMathToolsOC.h> - 但是我們這時在方法里是拿不到我們靜態庫中的方法實現的,因為我們並沒有在上面的主頭文件中導入MathTools.h頭文件.
- 導入MathTools.h頭文件,執行touchBegan方法,cmd + R運行程序
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { NSLog(@"%ld",[MathTools sumNum1:30 num2:40]); }- 發現程序崩潰了
// 動態庫不能被加載 dyld: Library not loaded: - 在ViewController.m文件中導入靜態庫的主頭文件
5.1.Bug1解決 - dyld: Library not loaded:
- 我們默認情況下編譯出來的.framework庫是一個動態庫
- 點擊工程 -> General 我們發現,系統在我們編譯時默認給我們添加了一個庫,在Linked Frameworks and Libraries位置
- 但是動態庫不是在這里添加,在上面的
Embedded Binaries處添加

- 這時在下面仍舊會為我們默認添加這個庫,但是這回不要把它刪了,運行
- 這時我們的靜態庫就可以被使用了
5.2.雖然上面.framework靜態庫可以被使用,但是它是個動態庫,一般開發中我們用的都是靜態庫
5.3.如何將我們編譯.framework改成靜態庫?
- 點擊工程 -> BuildSetting -> 搜索mach -> 改成Static Library

- 配置好后,重新編譯一下,然后將新的.framework文件拖入測試工程內,編譯(別忘了在靜態庫的主頭文件內導入MathTools.h文件)
5.4.但是仍舊存在一個CPU架構支持的問題
-
這個問題上篇.a靜態庫中有提及
-
上面是選擇的iPhone 7模擬器,在iPhone 5及真機上仍舊會報錯
-
如何解決?(其實步驟同上篇.a的bug解決步驟幾乎一樣)
- 仍舊是終端輸入lipo -info來檢測
- 發現支持x86_64
- 注意: 這里不能直接lipo -info我們的靜態庫文件,因為它本質和文件夾的作用是一樣的,要lipo -info它里面的MTYMathToolsOC這個exec文件.
-
兩種方法解決?
- 方法1:直接項目配置: 項目 -> Build Setting -> Build Active Architecture Only -> Debug 改為No(上篇文章有配圖)
- 方法2:弄兩個.framework文件,終端create合並(同.a文件的操作方法)
-
但是真機仍舊報錯
- 把.framework靜態庫選擇真機編譯一下
- 終端執行create命令合並成一個MTYMathToolsOC的exec文件,這個文件名必須一致,不能亂寫
- 合並之后查看新的靜態庫支持的CPU架構
Architectures in the fat file: MTYMathToolsOC are: i386 x86_64 armv7 arm64- 把MTYMathToolsOC文件拷貝到原來的庫文件中,替換掉原來的exec文件
- 就可以使用了
6.使用swift來創建測試工程,看靜態庫是否可用
- 創建swift工程
- 導入我們制作好的靜態庫文件到項目中
- 在ViewController.swift中,導入庫的頭文件,這里我們可以直接敲出來
import MathToolsOC
- 那么在touchBegan方法中能否敲出方法名呢,試驗一下發現並不能.
- 在swift中,導入庫的頭文件其實就是導入框架的主頭文件MathToolsOC.h,然而我們之前在MathToolsOC.h中並沒有把MathTools.h導入其中
- 所以把MathTools.h導入其中
- 運行報錯,因為我們並沒有配置動態庫那個步驟
錯誤信息
// 動態庫未加載
dyld: Library not loaded
-
配置過后就會發現,在swift中測試也沒有問題
-
注意點
1.為什么這次沒有把動態庫轉為靜態庫?
因為swift中是不支持靜態庫的,所以轉換的話,會報錯
2.動態庫轉靜態庫的方法見上面
二.用swift來創建.framework庫
-
其實步驟和前面差不多,最初創建時都會遇到這幾個問題?
- .framework默認創建出來是動態庫,要在General下面進行配置,在Embeded Binaries添加動態庫
- CPU支持的架構問題.這個同前面方法一樣,終端最后合並一下就好
-
由於步驟相差不大,這里就不再贅述了,但除了上面的bug還有有幾個注意點
- swift中不支持靜態庫,就是說以前我們創建的.framework庫默認是動態庫,最后要轉為靜態庫使用,這在OC中可以,但在swift中不可以,如果這里把動態庫轉為靜態庫的話,那么就會報錯
- swift創建靜態庫的時候, 類及類方法前面加上public,以便外界可以調用
