需求
- 有一个工程
test.project
,接入了自写的SDKSDK.framework
,SDK.framework
里同时有引用另外自写的other.framework
,每次都要一一添加,于是想把other.framework
融合进SDK.framework
,以后只需要添加一次就好了。
思路
思路1
-
SDK.framework
和other.framework
,进行多工程联调。把other.framework
当作SDK.framework
的子静态库,拿到重新封装后
的SDK.framework
给工程test.project
用。如图-1:- 结果:
- 直接运行
test.project
,报错。 - 把
other.framework
也导入test.project
中,运行成功。如图-2: -
test.project
的products
文件夹,右键show in finder
,发现SDK.framwork
和other.framework
并没有融合。如图-3:
- 直接运行
- 结论:这只是在
SDK.framework
中引用other.framework
联调的常规操作,并没有融合,需要在工程test.project
中导入other.framework
才能正确运行,与需求
不符。
- 结果:
思路2
- 把
other.framework
变成other.a
,把other.a
融合进SDK.framework
中,再把重新封装后
的SDK.framework
给工程test.project
用。如图-4:- 结果:
- 工程
test.project
只导入SDK.framework
,运行成功! -
test.project
的products
文件夹下,用命令class-dump
导出test.app
的.h
,发现静态库other.a
头文件也在里面,SDK.framework
的确融合了other.a
。如图-5:
- 工程
- 结论: 静态库
other.a
完全融合进SDK.framework
。符合需求
。
- 结果:
如何把 . framework变成 . a
情况1
-
other.framework
直接修改成other.a
。步骤:-
framework
只是个文件夹,打开other.framework
,找到同名的
/无后缀的
文件other
,直接改名->other.a
,选择添加该扩展名到文件末尾,拖到SDK.framework
中引用。 - 打开
other.framework
,找到Headers
文件夹,拖到SDK.framework
中引用。 - 融合,编译后的
SDK.framework
拖到test.project
中引用 - 运行
test.project
,完成。
-
情况2
-
other.framework
和SDK.framework
都是自己写的。会出现以下几种情况比较麻烦:- 每次修改
other.framework
后,要手动按照情况1
,把other.framework
->other.a
,进行融合,太麻烦。 - 把
other.framework
和SDK.framework
进行联调,是可以实时得到最新的other.framework
,随时联调。但是这种方式,test.project
需要同时拖入other.framework
和SDK.framework
,这样又不是本文的需求
。
- 每次修改
- 思路:
-
.framwork
和.a
都是静态库,本质上是一回事。 - 上面
情况1
,说明添加一下后缀就能实现.framework
->.a
。反过来去掉后缀,就变成了framework
中的二进制文件。
-
- 猜测:
- 那么我们建立一个静态库工程应该可以同时得到
.framework
和.a
两种不同后缀的静态库。(如图-5):
- 那么我们建立一个静态库工程应该可以同时得到
- 实践:
- 按照建立一个
framework
静态库的方法,建立一个叫other.framework
的工程,工程自动生成一个target
--->other
。 - 在工程上,新添加一个
target
叫libtest
。如图-6/图-7: - 运行静态库工程,成功,得到静态库
liblibtest.a
。如图-8: -
show in finder
,发现不仅有other.framework
,而且libtest.a
和头文件
还是齐全的。 - 按照常规导入
.a
静态库方法,把libtest.a
静态库导入SDK.framework
,联调成功! -
情况2
完成。
- 按照建立一个
细节修改
- 按照常规静态库工程方法,target
libtest
->Build Phases
->Headers
/Copy Fiels
,选择暴露libtest
的.h
文件 - 按照常规静态库工程方法,target
libtest
->Build Phases
->Compile Sources
,选择libtest
参与编译的.m
文件 - 设置target
libtest
,最高支持的iOS
版本:targetlibtest
->Build Settings
->Deployment
->iOS Deployment Target
->iOS10.xxx
- 设置target
libtest
,最高支持的iOS
版本:targetlibtest
->Build Settings
->Deployment
->iOS Deployment Target
->iOS10.xxx
- 设置target
libtest
头文件输出路径:targetlibtest
->Build Settings
->Packaging
->Public Headers Folder Path
->$(CONTENTS_FOLDER_PATH)/Headers
- 设置target
libtest
的名字:targetlibtest
->Build Settings
->Packaging
->Product Name
->随便取名
- 取消target
libtest
自动在名字前加上lib
:targetlibtest
->Build Settings
->Executable Prefix
->删掉lib
- 新建一个target
libtest
,配置好.h
/.m
后,运行报错,发现主头文件other.h
中的#import<other/aaa.h>
/#import<other/bbb.h>
都找不到,解决办法:- 设置一个宏定义,当前是编译
other.framework
时,主头文件other.h
加载:#import <other/aaa.h> #import <other/bbb.h>
- 设置一个宏定义,当前是编译
libtest.a
时,主头文件other.h
加载:#import <aaa.h> #import <bbb.h>
- 设置target
libtest
:targetlibtest
->Build Settings
->Apple Clang-Preprocessing
->Preprocessor Macros
->Debug
和Release
->FWMK=0
- 设置target
other
:targetother
->Build Settings
->Apple Clang-Preprocessing
->Preprocessor Macros
->Debug
和Release
->FWMK=1
- 主头文件
other.h
的代码修改为:#if FMWK #import <other/aaa.h> #import <other/bbb.h> #else #import <aaa.h> #import <bbb.h> #endif
- 利用
lipo
对不同arm
的.a
合并。
- 设置一个宏定义,当前是编译