需求
我们新建一个Swift类型的工程,由于种种原因,里面会有一些OC类,OC类用到了项目中的某些Swift类,而Swift类又用到了这些OC类,怎么解决?
解答
其实,Swift和OC文件是可以共存在一个工程中的,我们只需要简单的配置,和一些注意细节,就可以实现Swift和OC的混编。
步骤1:配置OC的桥接文件
1、在Swift里第一次新建OC的文件,会出现如图:
注意:以后再建,或者是拖入的OC文件,都不会有这个提示。
自己拖入的OC文件,需要手动配置桥接文件。
2、系统会自动创建一个头文件:工程名-Bridging-Header.h
3、如果想自定义这个头文件,把系统自动创建的删除,新建头文件:
4、配置自己的头文件:
步骤2:Swift调用OC代码
1、在桥接头文件里导入OC的头文件
2、OC文件对外提供一个方法
1 #import <UIKit/UIKit.h>
2
3 @interface OCVC : UIViewController
4
5 - (void)showOCInfo;
6
7 @end
1 #import "OCVC.h"
2
3 @interface OCVC ()
4
5 @end
6
7 @implementation OCVC
8
9 - (void)viewDidLoad {
10 [super viewDidLoad];
11 }
12
13 - (void)showOCInfo{
14 NSLog(@"这是OC的方法");
15 }
16
17 @end
3、swift直接使用swift的代码风格调用OC的方法就可以
1 import UIKit
2
3 class SwiftVC: UIViewController {
4
5 override func viewDidLoad() {
6 super.viewDidLoad()
7 view.backgroundColor = UIColor.white
8 }
9
10 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
11
12 // 创建OC控制器对象
13 let ocVC = OCVC()
14
15 // 调用OC控制器对象的方法
16 ocVC.showOCInfo()
17 }
18 }
步骤3:如果工程中的OC文件想使用某些Swift的文件,需要配置工程的swift头文件(系统生成:工程中找不到,但可以通过方法或属性点进去)
1、swift提供方法或属性,供外界调用
1 import UIKit
2
3 class SwiftVC: UIViewController {
4
5 override func viewDidLoad() {
6 super.viewDidLoad()
7 view.backgroundColor = UIColor.white
8 }
9
10 func showSwiftInfo() -> Void {
11 print("这是Swift方法")
12 }
13 }
2、oc的.m文件先导入头文件,才可以调用,注意:一定是.m文件导入,而非.h导入
#import "OCVC.h"
// 头文件:工程名-swift.h
// 注意了啊,这里导头文件的时候,只能.m文件中导入,.h中不能导入,否则会报错
// 还有,如果swift中声明的属性为 可选属性(?),那么对应的oc的头文件是不会有这个属性的)
#import "test-swift.h"
这时候,进行编译,有可能会出错,也有可能不会出错,如果出错的话,我们还需要手动配置一下。
我们可以先尝试配置ProdctName,一般都不会有问题,如果还是不行,再尝试配置ProductModuleName,然后进行编译。
3、这时候,我们的OC文件就可以愉快的使用OC的方式调用Swift代码了
1 #import "OCVC.h"
2 // 头文件:工程名-swift.h
3
4 // 注意了啊,这里导头文件的时候,只能.m文件中导入,.h中不能导入,否则会报错
5
6 // 还有,如果swift中声明的属性为 ?(即可选属性,那么对应的oc的头文件是不会有这个属性的)
7
8 #import "test-swift.h"
9
10 @interface OCVC ()
11
12 @end
13
14 @implementation OCVC
15
16 - (void)viewDidLoad {
17 [super viewDidLoad];
18 self.view.backgroundColor = [UIColor whiteColor];
19 }
20
21 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
22 {
23 // 创建swift的控制器对象
24 SwiftVC *swiftVC = [[SwiftVC alloc] init];
25
26 // 调用swift控制器对象的方法
27 [swiftVC showSwiftInfo];
28 }
29
30 @end