Can Objective-C code call Swift class extensions?
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 ?
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
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];
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)
}
}
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.
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