Swift混编踩坑指南

第一次在 OC 工程当中添加 Swift 文件或者在 Swift 工程当中添加 OC 文件时,Xcode 会提示你创建一个名称为{projectname}-Bridging-Header.h 的文件,点击 Create Bridging Header 创建。

Swift 调用 OC

在 {projectname}-Bridging-Header.h 导入需要调用的 OC 代码的头文件,即可在 Swift 代码中直接引用对应的类和变量

1
2
3
4
5
6
//
// Use this file to import your target's public headers that you would like to expose to Swift.
//

#import "SHOCUtil.h"
#import "SHTest.h"

OC 调用 Swift

在 Swift 代码中,给需要暴露给 OC 的类、方法和属性添加@objc 修饰符,Swift 的类需要继承自 NSObject

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import UIKit

class SHSwiftUtil: NSObject {

@objc static let startupText = "SHSwiftUtil startupText";


@objc class func startup() {
print("SHSwiftUtil class startup");
}

@objc func startup() {
print("SHSwiftUtil instance startup");
}
}

需要先在 Target->Build Settings->Product Module Name 当中设置值{A},最好是跟 Target 同名,然后在 OC 代码中导入头文件#import “{A}-Swift.h”即可调用 Swift 当中暴露的类、方法和属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#import "SHOCUtil.h"
#import "SHDemo-Swift.h"

@implementation SHOCUtil

+ (void)startup
{
NSLog(@"SHOCUtil class startup");
[SHSwiftUtil startup];
NSLog(@"%@",SHSwiftUtil.startupText);
}

- (void)startup
{
NSLog(@"SHOCUtil instance startup");
[[[SHSwiftUtil alloc] init] startup];
}

@end

在 Pod 库中混编

CocoaPods 帮我们做了相应工作,我们只需要引入相应的文件即可

OC 工程支持 Swift 建议

在 Podfile 中使用 use_modular_headers!选项替代不写或者 use_frameworks!选项。针对 OC 工程当中可能有比较多不规范的头文件导入(在需要使用#import <>的地方使用#import “”导入头文件)的情况,此种方式可以兼容不会报错。

重复定义类、方法、属性的问题

在使用 use_modular_headers!选项时,某些情况下会提示重复定义的问题,但是工程当中只有一份代码,这是因为底层 OC 代码使用的是#import “”引用头文件,在提供给多个不同的 Swift 库时,被导入了不同的 Module,而且作为该 Module 的一部分,此时编译器认为有多份代码存在。解决方案就是找到重复定义的文件,使其以#import <>的引用方式暴露给 Swift 即可。