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的情况)的主要内容,如果未能解决你的问题,请参考以下文章