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





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





8、最后編譯即可生成靜態(tài)庫(kù)。
打包framework注意事項(xiàng):
如果有storyboard、xib,需要在對(duì)應(yīng)的視圖控制器中添加以下代碼:
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:@"你的靜態(tài)庫(kù)名稱(chēng)" withExtension:@"framework"]];
if (bundle) {
// 如果是storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"你的storyboard名稱(chēng)(例如Main)" bundle:bundle];
self = [storyboard instantiateViewControllerWithIdentifier:@"你在storyboard中設(shè)置的此視圖控制器的id"];
return self;
// 如果是xib
self = [super initWithNibName:@"當(dāng)前控制器的名稱(chēng)" 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");
定義一個(gè)資源管理宏:
#define Debug_Env 0 // 開(kāi)發(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
這個(gè)資源管理宏也可以寫(xiě)得更方便些:
#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
加載圖片時(shí):[UIImage imageNamed:MR_BundleWith(@"picture.png")]
加載 storyboard 時(shí):[UIStoryboard storyboardWithName:@"Storyboard" bundle:MR_Bundle];
如果靜態(tài)庫(kù)中有 ClassA.h、ClassB.h、ClassC.h 三個(gè)頭文件,如果只對(duì)外暴露 ClassA.h,那么 ClassA.h 中就不能引用 ClassB 和 ClassC,只能在 ClassA.m 中引用。
合并最終的靜態(tài)庫(kù):
模擬器 iPhone5s 以下是 i386 架構(gòu),iPhone5s 及以上是 x86_64 架構(gòu)。
真機(jī)iPhone5s 以下是 armv7 架構(gòu),iPhone5s 及以上是 arm64 架構(gòu)。
終端 cd 到生成的 framework 文件夾中,使用命令 lipo -info framework名,可以看到打出的庫(kù)是 x86_64 架構(gòu)的。

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


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

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

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

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

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

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