iOS中OC与Swift互相桥接混编(注意项目中有多个TARGETS的情况)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS中OC与Swift互相桥接混编(注意项目中有多个TARGETS的情况)相关的知识,希望对你有一定的参考价值。

参考技术A Swift项目中桥接OC文件相对来说比较简单,一般在第一次创建OC文件的时候Xcode会弹出创建桥接头文件的提示

直接点击Create Bridging Header系统就自动为我们创建好了桥接头文件,并且自动将头文件路径配置好了,所以这种方式非常便捷

但是,有时候我们并不是第一次在Swift项目中创建OC文件时,Xcode并不会再为我们自动创建桥接文件,需要我们自己创建,然后配置路径。

我们自己新建一个.h文件。命名为xxx-Bridging-Header.h就行了,也可以随意命名,创建好以后,在Build Settings中找到上图中的Objecttive-C Bridging Header选项,然后将创建好的head文件拖到这个路径配置中,就可以了

然后在创建的这个head文件中#import需要使用到的OC文件。就可以在Swift中索引出OC文件的类了。

一般在OC项目中桥接Swift文件,只需要引入头文件#import "xxx-Swift.h"就可以在OC中调用Swift相关的类了。xxx为项目的Project Name

但是,在实际桥接中,常常会遇到报错'xxx-Swift.h' file not found,头文件找不到的情况。

因为项目配置中桥接头文件的名称有可能和我们项目名称不一致,所以会导致桥接头找不到。

这个时候我们需要检查Build Setting中的Objecttive-C Generated Interface Header Name选项是否和我们import的名称一样,需要改成一样的就可以解决报错问题了。

如图,如果这个选项中的名称为test-Swift.h,那么我们在OC中桥接的时候就应该为#import "test-Swift.h",才能不报错。

如果遇到项目中有多个TARGETS的情况,我们在创建相应的OC/Swift文件的时候需要选中所有需要桥接的TARGETS选项,才能在对应的TARGETS的Build Setting中看到对应桥接路径配置的选项,然后每个TARGETS的Head都需要配置一样

不然在切换到不同的TARGETS下以后,也有可能因为不同TARGETS下配置的Head不一致,导致在不同的TARGETS下再次出现'xxx-Swift.h' file not found的错误。

swift与oc混编

需求

我们新建一个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

 

 

以上是关于iOS中OC与Swift互相桥接混编(注意项目中有多个TARGETS的情况)的主要内容,如果未能解决你的问题,请参考以下文章

swift与oc混编

iOS开发之-- oc 和 swift混编之自建桥接文件

Swift与OC混编

iOS OC与Swift混编

在OC项目工程中混编Swift

IOS --- OC与Swift混编(转)