Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Syntax to Call Swift Method from Objective-C Class

I am trying to call some code in a Utilities file written in swift from an objective-c file.

Right now the class in the swift file looks like this:

class ImageClass: NSObject {
public func imageFromString(name: String?) -> UIImage? {
//code to make image

return image
}
}

I am trying to call it from the Objective-C file with:

 UIImage *myImage = [ImageClass imageFromString:@"test"];

however this is giving error:

Use of undeclared identifier 'ImageClass'

I know the Utilities file is reachable from the Objective-C file because I call other methods there though using a shared Instance.

Can anyone suggest the proper way to call the code? I actually don't care if it's a class or through a sharedInstance, I just need to be able to call it.

Edit:

As suggested by @Charles Srstka, I CMD-clicked on the #import myapp.swift file, jumped to Definition, and it shows the following in the header:

- (UIImage * _Nullable)imageFromStringWithName:(NSString * _Nullable)name SWIFT_WARN_UNUSED_RESULT;

Accordingly, I tried adding WithName (which I'd forgotten) to the invocation so I have:

 UIImage *myImage = [ImageClass imageFromStringWithName:@"test"];

but am still getting error with or without @objc before method:

No known class method for selector 'imageFromStringWithName:'
like image 642
user1904273 Avatar asked Feb 03 '19 19:02

user1904273


People also ask

Can I use Objective-C in Swift?

You can use Objective-C and Swift files together in a single project, no matter which language the project used originally. This makes creating mixed-language app and framework targets as straightforward as creating an app or framework target written in a single language.

Can Objective-C class conform to Swift protocol?

Mitrenegades solution is to use an objective-c protocol, is one way, but if you want a swift protocol, then the other would be to refactor the code so as to not use the objective-c class directly, but instead use the protocol (e.g. some protocol based factory pattern). Either way may be appropriate for your purposes.

What is Objcmembers?

Swift version: 5.6. By default Swift generates code that is only available to other Swift code, but if you need to interact with the Objective-C runtime – all of UIKit, for example – you need to tell Swift what to do.


1 Answers

In swift 4.2 and latest

  1. Add this line to your "*.m" file:

    #import "YourProjectName-Swift.h"
    
  2. Add @objc before your function:

    @objc public func imageFromString(name: String?) -> UIImage? {    
    //code to make the image
    return image
    }
    
  3. Call it inside Objective-C class:

    ImageClass *imgObject = [[ImageClass alloc] init];   
    UIImage *myImage = [imgObject imageFromStringWithName:@"test"];
    
like image 185
Bilal Bakhrom Avatar answered Oct 05 '22 23:10

Bilal Bakhrom