假设我有一些对象代码:
typedef NSString * ObjcNSString;
@interface ObjC : NSObject
+ (void)doThingsWithString:(nullable ObjcNSString)mid;
@end
上面objc代码对应生成的Swift接口是:
public typealias ObjcNSString = NSString
open class ObjC : NSObject {
open class func doThings(with mid: String?)
}
如果我在Swift:中使用代码,这会引起问题
let str: ObjcNSString? = nil
ObjC.doThings(with: str) // Cannot convert value of type 'ObjcNSString?' (aka 'Optional<NSString>') to expected argument type 'String?'
但我真的想在Swift中使用ObjcNSString
类型,有什么方法可以让它工作吗?
答案是使用NS_SWIFT_BRIDGED_TYPEDEF
作为问题的标题:
如何将objc typedef NSString作为字符串桥接到Swift?
我找到了NS_SWIFT_BRIDGED_TYPEDEF
,将其用于NSString的ObjC typedef,然后该类型将作为String桥接到Swift。
示例
无NS_SWIFT_BRIDGED_TYPEDEF
typedef NSString * ObjcNSString;
@interface ObjC : NSObject
+ (void)doThingsWithString:(nullable ObjcNSString)mid;
@end
对应的Swift接口为:
public typealias ObjcNSString = NSString
open class ObjC : NSObject {
open class func doThings(with mid: String?)
}
当我这样做的时候,这会给我带来错误:
let str: ObjcNSString? = nil
ObjC.doThings(with: str) // Cannot convert value of type 'ObjcNSString?' (aka 'Optional<NSString>') to expected argument type 'String?'
带NS_SWIFT_BRIDGED_TYPEDEF
为ObjC typedef:添加NS_SWIFT_BRIDGED_TYPEDEF
typedef NSString * ObjcNSString NS_SWIFT_BRIDGED_TYPEDEF;
@interface ObjC : NSObject
+ (void)doThingsWithString:(nullable ObjcNSString)mid;
@end
然后Swift界面变成:
public typealias ObjcNSString = String
open class ObjC : NSObject {
open class func doThings(with mid: ObjcNSString?)
}
同样的代码编译:
let str: ObjcNSString? = nil
ObjC.doThings(with: str)
所以我实现了我的目标:
但我真的想在Swift 中使用ObjcNSString类型
如果你仔细观察有或没有NS_SWIFT_BRIDGED_TYPEDEF
的Swift接口之间的差异,你会发现通过添加NS_SWIFT_BRIDGED_TYPEDEF
,我们得到了更理想的Swift界面。
生成的代码似乎不是您想要的。
您得到的错误是说您的函数需要String
类型,但您正试图使用ObjcNSString
类型。
要解决此问题,只需将函数声明更改为:
open class func doThings(with mid: ObjcNSString?)
但请记住,您可以在Swift中使用NSString。你不需要typealias。你也可以把你的函数写成:
open class func doThings(with mid: NSString?)