Obj-C混编Swift && Swift混编Obj-C
Swift引用OC实现通过桥接头文件,OC引用Swift实现直接importProductModuleName-Swift.h
OC引用Swift或者Swift引用OC都需要将Defines Module选项设为YES
TARGETS ->Build Settings -> Packaging 中 设置Defines Module为YES
第一次在Swift创建OC文件,或者第一次OC创建Swift时,xcode会提示桥接,Creat Bridging Header即可,这个文件用于Swift调用OC文件,与OC调用Swift无关。
手动创建桥接文件
首先介绍下这两个选项
product module name 产品??槊?/p>
product name 产品名称 Swift中的命名空间
路径
Target->Build Settings->all->packaging
在默认情况下,product module name和工程的Product Name一样。
在OC中引入Swift或Swift中引入OC会自动生成ProductModuleName-Bridging-Header.h的头文件用于Swift访问OC文件
如果修改的话切记要修改product name的话也要修改info.plist路径Info.plist.File 命名空间要与其一致
在Obj-C中混编Swift
- Defines Module 设置为YES
- OC引用Swift Xcode自动式实现的桥接文件命名方式是ProductModuleName-Swift.h
- 直接在OC项目中,import ProductModuleName-Swift.h即可
- 如果单纯OC调用Swift以上即可,不需要倒入什么桥接文件。
在Swift中混编Obj-C
- Defines Module 设置为YES
- Xcode在Swift中新建OC会生成ProductModuleName-Bridging-Header.h
//File > New > File > iOS > Source > Header File - 在ProductModuleName-Bridging-Header.h桥接文件中,直接import需要引用的OC文件即可。
说到product Name 这里说一下命名空间
OC中没有命名空间这一说,都是使用类前缀(Class Prefix),当作命名空间用区分名称相同的文件,苹果规定,两字前缀苹果拥有所有权,三个字母的前缀为开发者使用。但是不冲突就没事。例如AFNetWorking NSString MBProgressHUD ···
Swift中终于添加了命名空间,在任意类中打印一下self 会出现"命名空间.className"
注意。swift中的命名空间的使用不是一个项目,而是需要跨项目,在一个项目中,都是一个命名空间,在同一个命名空间下,所有全局变量或者函数共享,不需要import,从swift开始,官方更多的建议大家使用pod来管理第三方框架,不然倒入一个框架到处都可以用
swift获取product Name
根据类名转换成类的时候需要用到 product name + . + classStringName 也就是命名空间。
在这里需要说一下,OC Swift的命名空间的问题,别的语言都有命名空间这个概念唯独,OC Swift只有一个命名空间,就是它的Product Name
//这个key 在info.plist中source code打开即可看到。
//获取命名空间
guard let nameSpace = Bundle.main.infoDictionary!["CFBundleExecutable"] else {
print("获取命名空间
return
}
//根据类字符串转换
guard let VcClass = NSClassFromString("\(nameSpace).\(vcName)") else {
print("转换失败")
return
}
//类型转换
guard let viewController = VcClass as? UIViewController.Type else {
print("类型转换失败")
return
}
也可以创建一个Bundle的extension
extension Bundle {
//使用计算属性
var spaceName: String {
// return Bundle.main.infoDictionary?["CFBundleExecutable"] as? String ?? ""
return infoDictionary?["CFBundleExecutable"] as? String ?? ""
}
}
/**
guard let nameSpace = Bundle.main.infoDictionary!["CFBundleExecutable"] else {
print("获取命名空间
return
}
*/
//上边的获取命名空间就可以写成这个
guard let spaceNamee = Bundle.main.spaceName else {
print("获取失败")
}