Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call Swift func from Objective-C with parameter

I want to integrate a Swift class into an UIViewController class. I think I made all settings correct. I have a class rURLTask:NSObject with a function:

@objc public func primer() {
    print("primer")
}

In my .swift file and can call it from my Objective-C-class with:

[URLTask primer];

and it prints nicely. Another function is:

@objc public func ladeURL(url: URL?) {
    print("loadURL")
}

but this one I cannot call from Objective-C. I try to write:

NSURL* testURL = [NSURL URLWithString:@"http://www.google.com"];    
[URLTask ladeURL:testURL];

I get the error:

No visible @interface for 'rURLTask' declares the selector 'ladeURL:'

I think there is a very basic mistake. Using Objective-C in Swift 3 in another project worked well.

like image 787
heimi Avatar asked Dec 11 '22 06:12

heimi


2 Answers

The reason you cannot call

@objc public func ladeURL(url: URL?) {
    print("loadURL")
}

by saying

[URLTask ladeURL:testURL];

is that ladeURL: is not the name of this method as far as Objective-C is concerned. That is what the compiler means when it says that "No visible @interface for 'rURLTask' declares the selector ladeURL:".

Its name as far as Objective-C is concerned is ladeURLWithUrl:. That is because you have exposed the url: parameter name as an external label.


If it was important to you to be able to say

[URLTask ladeURL:testURL];

in Objective-C, you could have declared ladeURL like this:

@objc public func ladeURL(_ url: URL?) {
    print("loadURL")
}

See the underscore? That hides the external label of the parameter.


Another solution, allowing you to keep the url: external label, would be to declare the Objective-C name as part of the objc attribution:

@objc(ladeURL:) public func ladeURL(url: URL?) {
    print("loadURL")
}

That says to the compiler: "I know you would like to translate the name of this method into Objective-C as ladeURLwithUrl:, but don't; translate it as ladeURL: instead."

like image 169
matt Avatar answered Jan 07 '23 08:01

matt


When you import the class to OC , the name of the method written in swift is translated concatenated with the withParameterType , as prime method

@objc public func primer() {
  print("primer")
}

has no parameters it can be called like this

[URLTask primer];

but this

@objc public func ladeURL(url: URL?) {
   print("loadURL")
}

is translated to

[URLTask ladeURLWithUrl:<#NSURL#>];
like image 28
Sh_Khan Avatar answered Jan 07 '23 09:01

Sh_Khan