如何将objc-typedef NSString作为字符串桥接到Swift



假设我有一些对象代码:

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?)

最新更新