error: Using bridging headers with framework targets is unsupported

真是各种骚操作。

1. 起因

事情是这样的,最近工作上在做一些app的拆分,在一套代码中,编译不同的源文件。

简单理解在编译之前就做了ABTest。

其中一个T类,实现了Y协议,但是

  • 在A App中,它需要实现协议的a方法;
  • 在B App中,它需要实现a方法;

这个T类是由Objectiove-C实现的,而我们有一个用于区分A/B的工具类(A和B都各自实现了一份)是Swift实现的。

2. 两种实现方式

2.1 针对未模块化的App 官方姿势

Bridging Header
使用 Objective-C bridging header,标准姿势,创建xxx-Bridging-Header.h文件(xxx是你的项目名称)将Swift要引用OC的类放到这个文件里即可。

如果整套文件属于App中,就是没有模块化,那么你只需要设置路径即可
Bridging路径设置

那么你就可以在B App 这个工具 Swift 类里,实现一个 extension

// Y协议
@objc extension Y
{
    // 协议方法a
    public func a() -> UIView {
        xxx
        xxx
        xxx
    }
}

在A App 这个工具 Swift 类里,什么都不需要做。

2.2 针对模块化的Framework 官方姿势

如果你的App已经分模块了,并使用了一些组件化的工具例如Cocoapods,那么我们很容易想到,该去该组件的 podspec 文件里添加

spec.pod_target_xcconfig = {
    'SWIFT_OBJC_BRIDGING_HEADER'=>'${PODS_TARGET_SRCROOT}/xxx/xxx-Bridging-Header.h'
}

好的,添加完后,我们去构建该组件。
这时候我们遇到了

- error: Using bridging headers with framework targets is unsupported (in target 'xxx' from project 'xxx')
- error: Using bridging headers with module interfaces is unsupported (in target 'xxx' from project 'xxx')

纳尼,为什么会这样?

然后就去搜索,看到了官方文档,【见参考文献1】

简单理解 ``xxx-Bridging-Header.h` 这种声明明方式,在Framework里不起作用了。

我们需要先设置 Defines ModuleYES
Defines Module

然后将Swift需要引入的的那个OC类的头文件 设置 为 Public
Header

这样你才可以在Swift文件里引入OC的类。

这样有一点不好的是,我们这个对外其实并不想暴露 这个T类。

那有没有其他方法呢?

2.3 骚操作

当然,我们还有其他骚操作。

就当前这个case来说,我们可以分别在A和B两套代码里,使用替换来解决这个函数的实现。

在B App中,我们实现C.h 定义 宏

#define ABTest_VIEW() \
- (UIView *)a{\
    xxx;\
}\

在A App中,我们实现C.h 定义 宏

#define ABTest_VIEW() 

这样,我们在需要实现的 T类中 直接使用 宏 ABTest_VIEW()

然后对该文件执行 Preprocess
Preprocess

然后你就会发现,

  • 在A App的 T类实现里没有 a 方法;
  • 在B App中 T类实现里有 a 方法;

这算是一种骚操作吧,这样我们就不会破坏这个库的Public

4. 未完待续

这个编写A/B App的骚操作还在继续。。。

参考文献

  1. Importing Objective-C into Swift | Apple Developer Documentation
  2. Importing Swift into Objective-C | Apple Developer Documentation