Can Objective-C code call Swift class extensions?

Objective CSwiftSwift Extensions

Objective C Problem Overview


I searched some posts, I think I cannot write an extension under Swift, and call it from Objective-C code, right?

@objc like attributes only support methods, class, protocols ?

Objective C Solutions


Solution 1 - Objective C

You can write a Swift extension and use it in Objective-C code. Tested with Xcode 6.1.1.

All you need to do is:

  • create your extension in Swift (@objc annotation needed since Swift 4.0.3)

  • #import "ProjectTarget-Swift.h" in your Objective-C class (where "ProjectTarget" represents the XCode target the Swift extension is associated with)

  • call the methods from the Swift extension

Solution 2 - Objective C

I found out that in Swift 4.0 I had to add @objc in front of my extension keyword in order for the Swift extension methods to become visible by an instance of the Objc class I was extending.

In short:

File configuration setup:

CustomClass.h
CustomClass.m
CustomClassExtension.swift

In CustomClassExtension:

@objc extension CustomClass
{
    func method1() 
    {
        ...
    }
}

In my AppDelegate.m:

self.customClass = [[CustomClass alloc] init];
[self.customClass method1];

Solution 3 - Objective C

This solution works for Swift 2.2 and Swift 3. Note that only extensions for classes (not for structs or enums) will be accessible from Objective-C.

import UIKit

extension UIColor {

    //Custom colours
    class func otherEventColor() -> UIColor {
        return UIColor(red:0.525, green:0.49, blue:0.929, alpha:1)
    }
}

Then #import "ProductModuleName-Swift.h" in your ObjC file.

Swift 4

extension UIColor {

    // As of Swift 4.0.3, the @objc annotation is needed if you want to use the extension in Objective-C files
    @objc
    class func otherEventColor() -> UIColor {
        return UIColor(red:0.525, green:0.49, blue:0.929, alpha:1)
    }
}

Solution 4 - Objective C

As covered in the other answers, importing the generated Swift header works in most cases.

An exception to this is when the category is defined on a bridged type (i.e. the extension is defined on String and not NSString). These categories will not automatically be bridged to their Objective-C counterparts. To get around this, you'll either need to use the Objective-C type (and cast the return value in your Swift code with as String) or define an extension for both the Swift and Objective-C types.

Solution 5 - Objective C

Import "#import "ProductModuleName-Swift.h" header in objective-c file and add @objc infront of your extentsion in swift file. It will working fine in swift 4.2 and swift 5

Solution 6 - Objective C

If think you have configured everything correctly (marked your Swift entities with @objcMembers or @objc, imported the bridging header "ProductModuleName-Swift.h" and so on) – but still getting the No visible @interface for 'FooClass' declares the selector 'fooSelector' error:

Check if you see your interfaces in the bridging header by ctrl + cmd clicking on it. If you don't, check out my answer to this question: Swift to Objective-C header does not contain Swift classes

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsprhawkView Question on Stackoverflow
Solution 1 - Objective Cmarius bardanView Answer on Stackoverflow
Solution 2 - Objective CReyAndReyView Answer on Stackoverflow
Solution 3 - Objective CFoti DimView Answer on Stackoverflow
Solution 4 - Objective CmclaughjView Answer on Stackoverflow
Solution 5 - Objective CRanjaniView Answer on Stackoverflow
Solution 6 - Objective CTysacView Answer on Stackoverflow