从 Objective-C 调用字符串扩展,包括用 Swift 编写的函数

Call String extension including function written in Swift from Objective-C

当 Swift 中的扩展仅使用如下变量时:

 extension NSString   {
        var isNumber: Bool {
            return length > 0 && rangeOfCharacter(from: CharacterSet.decimalDigits.inverted).location == NSNotFound
        }
    }

我可以使用非常友好的语法从 Objective-C 调用它:

NSString *str = @"twelve";
BOOL isNumber = str.isNumber;  

然而,当扩展使用如下函数时,我在语法上苦苦挣扎:

extension String {
 func asImage(withAttributes attributes: [NSAttributedString.Key: Any]? = nil, size: CGSize? = nil) -> UIImage? {
        let size = size ?? (self as NSString).size(attributes: attributes as! [String : Any])
        if #available(iOS 10.0, *) {
            return UIGraphicsImageRenderer(size: size).image { _ in
                (self as NSString).draw(in: CGRect(origin: .zero, size: size),
                                        withAttributes: attributes as! [String : Any])
            }
        } else {
            // Fallback on earlier versions
            return nil
        }
    }

这可以从 Swift 调用,只需:

 var image = "Hello World".asImage()

但我不知道如何从 Objective-C 调用它。

事实上,autotype 甚至无法识别 str.asImage,当我尝试各种操作时,它会把我引向一个充满错误的兔子洞并修复它,从而导致其他错误。

如何从 Objective-C 调用上述分机?

A Swift class、扩展或协议只能在 Objective-C 中表示,如果它是可转换的或明确标记为 @objc.. 这意味着它需要所有参数也可以转换为 Objective-C。

struct 也无法转换,因此我们只剩下 classes(IE:classes 的扩展和具体的 classes)并标记一个class@objc,它必须继承NSObject.

示例:

@objc
extension NSString {
    func asImage(withAttributes attributes: [NSAttributedString.Key: Any]? = nil, size: CGSize = .zero) -> UIImage? {
        let size = size == .zero ? self.size(withAttributes: attributes!) : size
       if #available(iOS 10.0, *) {
           return UIGraphicsImageRenderer(size: size).image { _ in
               self.draw(in: CGRect(origin: .zero, size: size),
                                       withAttributes: attributes!)
           }
       } else {
           // Fallback on earlier versions
           return nil
       }
   }
}

请注意,我将 CGSize 参数更改为非可选参数并与零进行比较..

另请注意,我将其标记为 @objc 并将其更改为 NSString 的扩展名,因为 String 本身无法转换为 Objective-C,因为它是 [=13] =]!

然后在Objective-C中你可以这样称呼它:

[str asImageWithAttributes:@{....} size:CGSizeZero];

或任何你想要的参数..