6

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:'

2 Answers 2

8

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"];
    
Sign up to request clarification or add additional context in comments.

2 Comments

This did the job. Key was initiating the NSObject prior to invoking class method. Thanks.
A note about project name, if there are spaces in the project name make sure you replace them with underscores, for example if the project name is "My Project" you need to write it as #import "My_Project-Swift.h"
1

Add this line to your Objective-C file:

#import "YourProjectName-Swift.h"

Replace YourProjectName with the name of your project. This will make all the Objective-C-compatible Swift classes in your project visible to your Objective-C code.

Note that you'll also need to add the @objc annotation to your func declataions to make the methods visible to Objective-C.

4 Comments

I had the import statement already. I added the @objc before public in the function line but am getting same error.
If you command-click on the #import line, you should be able to see the generated header file. Does your class show up in there?
I tried your suggestion which I've put into an edit above. Seems like there is a method there, but I still am not calling it correctly
@user1904273 Your problem was that you needed to instantiate the object (you could have called it the way you did if it were a class func instead of a regular func), but I see someone else already got that one. If you want to fix that awkward method name, though, you can declare the method as func image(string name: String?) which will show up in Objective-C as imageWithString:, or you could do func imageFromString(_ name: String?) which will show up as imageFromString:. You can also put an @objc(whateverTheHellYouWantToCallIt:) annotation on the func if you prefer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.