swift framework 混编是个比较蛋疼的事情,很多东西都没有资料,特别是modulemap这块。
现在在这里给大家总结一下经验。
swift framework混编情况
1、swift framework 混编引入oc 代码
2、swift framework 混编引入oc的第三方库(framework、.a)
首先要注意的概念就是,swift framework所引入oc的东西,都要先经过modular,即是模块化(详细自行查阅clang相关的module概念,这个东西并不是swift独有的)。
1、swift framework 混编引入oc 代码:
其实这个问题很好解决,网上也有很多文章。本质就是需要将oc代码先modular,再提供给swift调用。而实现这个过程就是使用modulemap去配置。
当你配置好后,在swift代码直接import定义的module就可以使用
2、swift framework 混编引入oc的第三方库(framework、.a):
framework是封装的形式,静态framework本质还是.a库。需要特别注意的是,framework包中,如果包含了modulemap文件,那么这个framework已经被modular了,使用时,设置好依赖关系和build setting中的framework search path,就可以直接import使用。
需要处理难点就是没有modulemap的framework和.a库。
(1).a库的处理相对简单,跟引入oc代码类似。先设置好依赖,然后将.a库的头文件写到modulemap中,设置build setting中的library search path,就可以import使用。
(2)没有modulemap的framework(non-modular framework)的处理有几种方式:
核心思想都是想办法将framework modular
第一种就是将framework转换成.a库,其实就是改文件扩展名就可以,然后通过上面(1)的方式就可以使用。
第二种就是先设置好依赖,然后build setting设置好framework search path,最后使用modulemap 直接通过路径引用framework的所有头文件或者unbrella header,就可以import使用。(注意,这里会碰到路径问题,如果想使用相对路径,则需要在build rules下添加run script,在编译时才生成modulemap,而不是直接编写modulemap)
第三种就是,framework外面再包一层framework(相当于容器framework,容器framework的build setting中的Define modules需要设置成YES),所有framework的头文件重新暴露出去,供外部使用。(使用这种方法有风险,笔者在使用时,protobuf库会出现不正常,具体原因没有找到)
通过以上方式可以解决framework混编的问题了。
然而这并没有结束。
因为当主工程使用时,会遇到麻烦。因为第三方framework的调用可能并不只有1个swift framework在使用,可能多个framework在共同调用,主工程也在调用,如果使用混乱,会出现各种各样的依赖和引用的死结。
由于每个工程的依赖关系都不一样,所以这里只能提供方法论。
你需要:
(1)先按层级梳理好工程的依赖关系,最好画图。
(2)遇到底层静态framework,建议使用容器framework去重新包裹framework
常见问题:
(1)duplicate symbol,这个问题是工程链接发现了重复的symbol(相当于重复定义)。遇到这个问题,多半是依赖关系没有处理好,例如,modulemap引用了一份.a库,主工程又同样引用了一份.a库,假如主工程有一个文件同时引用了这个module和.a库,就会出现这个问题。出现这个问题,多检查报错的文件的import关系,是不是出现重复引用的情况。
(2)import non-modular framework,这个是swift报错,原因使用了没有modular的framework。有两种可能,第一种swift framework报错,主要是modulemap没有处理好,第二种可能是主工程的swift报错,这个也跟引用相关,主要原因是没有梳理好文件的import关系。