1

I have a a String extension which i want to use on NSString from objective c. As String in swift is a struct so its not exposed to objective c. So in order to call it from objective c i defined an extension on NSString in the same file.

public extension NSString {

        func htmlAttributedStringWithFont(font: UIFont, size fontSize: CGFloat = 17.0) -> NSAttributedString? {
            let str = self as String
            return str.htmlAttributedStringWithFont(font: font)
        }

    }



   extension String {

        /// Converts an HTML String to NSAttributedString
        ///
        /// - Returns: NSAttributedString?
        func htmlAttributedString() -> NSAttributedString? {
            guard let data = self.data(using: .utf16, allowLossyConversion: false) else {
                return nil
            }
            guard let html = try? NSMutableAttributedString(
                data: data,
                options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
                documentAttributes: nil) else { return nil }
            return html
        }

        /// returns and NSAttributedString optional from HTML content after applying specific font and size
        ///
        /// - Parameters:
        ///   - font: Font to be applied on the returned string
        ///   - fontSize: Size to be applied on the returned string
        /// - Returns: NSAttributedString?
        func htmlAttributedStringWithFont(font: UIFont, size fontSize: CGFloat = 17.0) -> NSAttributedString? {
            let string = self.appending(String(format: "<style>body{font-family: '%@'; font-size:%fpx;}</style>", font.fontName, fontSize))
            return string.htmlAttributedString()
        }
}

The above two extensions are in the same file String+Extension.swift. I then tried to call the htmlAttributedStringWithFont method from my objective c class with NSString

[str htmlAttributedStringWithFont:[UIFont systemFontSize]];

it gives me the following error

 No visible @interface for 'NSString' declares the selector 'htmlAttributedStringWithFont:'

Any idea how i can use String extension in Swift from Objective c NSString

Madu
  • 4,849
  • 9
  • 44
  • 78
  • I believe functions with default argument are not exposed to objc. Try writing `@objc func htmlAttributedStringWithFont(font: UIFont, size fontSize: CGFloat = 17.0) -> NSAttributedString?` and check if it returns errors. – Adamsor Aug 28 '17 at 13:22
  • Still the same error. – Madu Aug 28 '17 at 13:26
  • 1
    https://stackoverflow.com/questions/27097688/can-objective-c-code-call-swift-extension-on-class Looks like swift/xcode might generate obj-c headers that need to be imported – solenoid Aug 28 '17 at 14:01
  • Check if you have a line importing the header `#import "YourProjName-Swift.h"` in the ObjC file. If you really have it, cmd-click on it. You may find the extension method is exposed to ObjC as `htmlAttributedStringWithFontWithFont:size:`. **ObjC name is synthesized from method name and parameter labels.** **No default parameter is supplied when calling the method from ObjC.** You need to use it as `[str htmlAttributedStringWithFontWithFont:[UIFont systemFontSize] size: 17.0];`. – OOPer Aug 28 '17 at 18:57
  • Great it worked it was actually `htmlAttributedStringWithFontWithFont ` instead of `htmlAttributedStringWithFont`. Thanks @OOPer – Madu Aug 29 '17 at 07:28

1 Answers1

0
  1. If you are working on Swift and Objective-C files in same project, then there is a certain file called YourProjectName-Swift.h which is created automatically for you by xCode.
  2. Suppose there is a Swift extension you did create or update just now.
  3. This should update YourProjectName-Swift.h automatically and then by importing this header file (#import "YourProjectName-Swift.h") in your Objective-C Class you can use Swift code.
  4. Just in case, if it doesn't then you can manually update this header file.
Muhammad Waqas
  • 904
  • 2
  • 10
  • 21