制作 .framework 靜態(tài)庫的步驟:
1、將需要打包成 Framework 的模塊導入到項目中,設置最低支持的 iOS 版本,編譯項目保證不報錯。





4、把 Podfile 中所有庫注釋掉然后 pod install,然后刪除 Podfile 文件同級別目錄下其它所有 pods 相關(guān)的文件。





8、最后編譯即可生成靜態(tài)庫。
打包framework注意事項:
如果有storyboard、xib,需要在對應的視圖控制器中添加以下代碼:
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:@"你的靜態(tài)庫名稱" withExtension:@"framework"]];
if (bundle) {
// 如果是storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"你的storyboard名稱(例如Main)" bundle:bundle];
self = [storyboard instantiateViewControllerWithIdentifier:@"你在storyboard中設置的此視圖控制器的id"];
return self;
// 如果是xib
self = [super initWithNibName:@"當前控制器的名稱" bundle:bundle];
return self;
}
return [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
}
如果需要加載圖片:
NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:@"Frameworks" withExtension:@"framework"]];
NSString *bundlePath = [bundle resourcePath];
UIImage *img = [UIImage imageWithContentsOfFile:[bundlePath stringByAppendingString:@"/aaa.png"]];
使用圖片宏:
#define Bundle_With_Framework(name) [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:name withExtension:@"framework"]]
#define Framework_Bundle Bundle_With_Framework(@"Frameworks")
#define ImageNamed(name) Framework_Bundle ? [UIImage imageWithContentsOfFile:[[Framework_Bundle resourcePath] stringByAppendingString:[NSString stringWithFormat:@"/%@", name]]] : [UIImage imageNamed:name]
self.img.image = ImageNamed(@"gg.jpg");
定義一個資源管理宏:
#define Debug_Env 0 // 開發(fā)環(huán)境
#define Release_Env 1 // 打包環(huán)境
#if Release_Env
#define MR_Bundle [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:@"StaticLibrary" withExtension:@"framework"]]
#define MR_BundleWith(res) [[MR_Bundle resourcePath] stringByAppendingPathComponent:res]
#else
#define MR_Bundle [NSBundle mainBundle]
#define MR_BundleWith(res) res
#endif
這個資源管理宏也可以寫得更方便些:
#define Framework_Bundle [[NSBundle mainBundle] URLForResource:@"MRFramework" withExtension:@"framework"]
#define MR_Bundle Framework_Bundle ? [NSBundle bundleWithURL:Framework_Bundle] : [NSBundle mainBundle]
#define MR_BundleWith(res) Framework_Bundle ? [[[NSBundle bundleWithURL:Framework_Bundle] resourcePath] stringByAppendingPathComponent:res] : res
加載圖片時:[UIImage imageNamed:MR_BundleWith(@"picture.png")]
加載 storyboard 時:[UIStoryboard storyboardWithName:@"Storyboard" bundle:MR_Bundle];
如果靜態(tài)庫中有 ClassA.h、ClassB.h、ClassC.h 三個頭文件,如果只對外暴露 ClassA.h,那么 ClassA.h 中就不能引用 ClassB 和 ClassC,只能在 ClassA.m 中引用。
合并最終的靜態(tài)庫:
模擬器 iPhone5s 以下是 i386 架構(gòu),iPhone5s 及以上是 x86_64 架構(gòu)。
真機iPhone5s 以下是 armv7 架構(gòu),iPhone5s 及以上是 arm64 架構(gòu)。
終端 cd 到生成的 framework 文件夾中,使用命令 lipo -info framework名,可以看到打出的庫是 x86_64 架構(gòu)的。

如果想同時支持 i386 和 x86_64,設置:
Build Settings —> Architectures —> Build Active Architecture Only —> NO。


模擬器選擇真機,編譯之后會生成真機的 framework ,架構(gòu)是 armv7 和 arm64。

以上真機和模擬器的 framework都是 DEBUG 模式下的,打開 Scheme,選為 Release 模式再編譯兩次(真機和模擬器):

使用命令:lipo -create path1 path2 -output 合成文件名
可以將真機和模擬器兩個 framework 合成為一個。其中 path1 和 path2 都是下圖中紅圈中的文件:

注意,一般是 debug 真機跟 debug 模擬器合成,release 真機跟 release模擬器合成,debug 和 release 不要混合,當然,兩個模擬器或者兩個真機合成會失敗。最終會分別有一個 debug 下和 release 下的 framework。
framework靜態(tài)庫使用步驟:
1、將靜態(tài)庫拖入工程,然后在 Build Phases —> Copy Bundle Resources 中添加該靜態(tài)庫。

2、如果靜態(tài)庫中有分類(Category),則需要在 Build Settings —> Other Linker Flags 中添加 -ObjC 或 -all_load,如果靜態(tài)庫調(diào)用 pods 中的第三方庫崩潰,則添加$(inherited)。(-ObjC鏈接所有OC文件,-all_load是鏈接所有文件,-force_load文件路徑是鏈接指定路徑文件,多個靜態(tài)庫文件沖突時使用-force_load,$(inherited)的含義)

3、如果靜態(tài)庫中引用了AFNetworking等第三方庫,需要工程也導入這這些庫,否則會報頭文件找不到的錯誤。
4、如果使用者導入靜態(tài)庫頭文件報警告 missing submodule ,說明靜態(tài)庫中有頭文件找不到。如果打包工程名和某個類的名稱相同,也會報這個警告,只需要把這個類名改成其它名稱即可。
參考《iOS靜態(tài)庫》、《打包Framework并引用CocoaPods管理》。
一般打包了靜態(tài)庫之后,還需要制作說明文檔,文檔制作可參考《安裝和使用AppleDoc》和《使用AppleDoc自動生成項目文檔》。