和Swift模块化混编方案
背景
目前的工程是纯OC的工程,并且已经使用了Cocoapods实现模块化管理。为了与时俱进,现需要引入swift到工程,并且能够让cocoapods管理的Swift模块与OC模块相互调用。
混编方案
1.添加空的Swift文件到主工程,比如叫XXMain.swift
注意:主工程必须要有一个Swift文件,使得Xcode支持Swift编译。
创建的时候会弹出是否需要创建 Bridging-Header桥接文件,这里可以不用创建。模块化做的比较好的情况下,主工程模块中添加Bridging-Header文件其实也用不上。
cocoapods自动管理modulemap用于暴露swift类以及引入其他OC类。
2.修改iOS最低支持的版本号为12.3
注意:swift5开始 ABI才稳定,而从iOS 12.3开始 系统内包含swift5。
创建的时候会弹出是否需要创建 bridge桥接文件,这里不需要创建。创建bridge文件之后,可能会导致cocoapods模块下的swift文件报 找不到OC类的错误。
cocoapods自动管理modulemap用于需要暴露的swift类以及引入其他OC类。
3.引入OC到Swift模块
注意:我的Swift代码会根据业务分成不同的模块,通过cocoapods去管理。此时需要在模块中添加一个h头文件用于引入OC类,文件头的名称要与模块 “名称一致” ,比如pods模块名称为XwjModule,那么你需要创建一个XwjModule.h文件夹用于包含需要引入的OC头文件。
如果没有同名头文件,会导致无法调试Swift模块代码
4.Podfile和PodSpec
注意:
Podfile中需要使用use_modular_headers!方式兼容OC与Swift混编
PodSpec文件中source_files中除了包含swift文件,还要包含第3步中创建的头文件。
Podfile文件
PodSpec文件
二进制化Swift模块
注意:上述四个步骤已经可以完成OC与Swift的混合开发了,如果此刻不想把Swift源码暴露出来,那么就需要将Swift模块二进制化。
1.合并静态库
通过上述混编方案,我们已经可以进行正常开发,此时,我们分别在"Debug 模拟器模式" / "release 真机模式"执行build,
可以得到Xcode编译的所有的a静态库文件。找到其中Swift模块对应的静态库,并且执行lipo -create命令合并静态库。
2.头文件
找到静态库依赖的头文件,以SwiftJSSDKModule为例子,Xcode编译之后会生成libSwiftJSSDKModule.a静态库,
同时还会生成SwiftJSSDKModule-Swift.h 和 SwiftJSSDKModule-umbrella.h文件。
SwiftJSSDKModule-Swift.h实际上是Xcode把Swift代码翻译成了OC代码,使得其他的OC代码可以引用其对象
SwiftJSSDKModule-umbrella.h 实际上是包含了Swift模块自己需要引入的OC头文件
3.二进制化的PodSpec
二进制化后,我们只需要包含a静态库、SwiftJSSDKModule-Swift.h 和 SwiftJSSDKModule-umbrella.h即可完成模块配置了。
这里分享一个小技巧,使用一个宏IS_BINARY 和 {s.name}_SOURCE 用于动态的切换二进制化模式和代码模式。具体方式如图:
最后
对于OC与Swift混编的处理方式就分享到这里 还有其他疑问的同学可以在留言,我们可以一起讨论。下篇打算分享下 Swift与OC交互之ModuleMap的作用