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 ?
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];
@nonobjc
annotation. –
Moorhead 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)
}
}
public
is needed? Works fine without public
modifier for me. Are we assuming that the extension is not in the same project but being imported from another project? –
Godber 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.
public extension NSString
. Should you get an unresolved identifier or similar error at compile time, you can cast again back to String e.g. let sVal = self as String
and then call the necessary code on sVal
–
Cherrylchersonese mclaughlinj
said, for both NSString class and String struct –
Roca 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
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
© 2022 - 2024 — McMap. All rights reserved.