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即可。