Расширение Call String, включая функцию, написанную на Swift из Objective-C - PullRequest
1 голос
/ 17 октября 2019

Когда расширение в 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.

На самом деле, автозапуск даже не распознает str.asImage, и когда я пробую разные вещи, он приводит меня в кроличью нору ошибок и исправляет их, которые приводят к другим ошибкам.

Какя бы назвал вышеуказанное расширение из Objective-C?

1 Ответ

1 голос
/ 17 октября 2019

Класс, расширение или протокол Swift могут быть представлены в Objective-C, только если они конвертируемы или явно помечены @objc .., что означает, что все параметры также должны быть преобразованы в Objective-C.

struct также не может быть преобразовано, поэтому мы оставляем только одни классы (IE: расширения для классов и конкретные классы), и чтобы пометить класс @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, поскольку это struct!

Тогда в Objective-C вы можете назвать это так:

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

или любые другие параметры, которые вы хотите ..

...