Reputation: 109
I have a problem with the Swift and Objective-C interoperability. In my Objective-C class the methods with parameters of my Swift class are not recognized. I have integrated the Swift class with the Bridging-Header correctly. Furthermore the Swift class inherits from NSObject and the variables and methods are declared with @objc. I have also tried @objcmembers... I can't find a solution to my problem on the internet. I am really desperate. My Swift class uses classes from other projects, which are also declared with @objc. Below is an example of my problem:
Project A: SwiftClassA
public class SwiftClassA: NSObject {
@objc public init() {
// do something
}
@objc public func aFunction() {
// do something
}
}
Project B: SwiftClassB
import ProjectA
public class SwiftClassB: NSObject {
@objc public init(testA: Double, testB: Double) {
// do something
}
@objc public func bFunction() {
let classA = SwiftClassA()
// do something
}
}
Project C: SwiftClassC
import ProjectA
import ProjectB
public class SwiftClassC: NSObject {
@objc public var classA: SwiftClassA
@objc public init(classA: SwiftClassA) {
self.classA = classA
}
@objc public func cFunction(testA: Double, testB: Double) {
let classB = SwiftClassB(testA: testA, testB: testB)
// do something
}
@objc public func cFunction() {
// do something
return
}
}
Project C: ObjcClass
#import <ProjectA-Swift.h>
#import <ProjectC-Swift.h>
@property (nonatomic, strong) SwiftClassC *swiftClassC;
@implementation ObjcClass
- (ObjcClass *_Nonnull)init {
SwiftClassA *swiftClassA = [[SwiftClassA alloc] init];
_swiftClassC = [[SwiftClassC alloc] initWithClassA: swiftClassA];
return self;
}
- (void)objcFunction {
[_swiftClassC cFunctionWithTestA: 1.0 testB: 1.0]; // Property ‚FunctionWithTestA' not found on object of type ’SwiftClassC *’
[_swiftClassC cFunction];
}
@end
Upvotes: 2
Views: 1441
Reputation: 16725
Without actually seeing the project, it's tough to diagnose, however I would recommend not putting @objc
in front of everything within your Swift classes. Instead, put @objcMembers
in front of your Swift class declaration.
Your declarations would look like this:
@objcMembers
public class SwiftClassA: NSObject {
public override init() {
// do something
}
public func aFunction() {
// do something
}
}
@objcMembers
public class SwiftClassB: NSObject {
public init(testA: Double, testB: Double) {
// do something
}
public func bFunction() {
let classA = SwiftClassA()
// do something
}
}
@objcMembers
public class SwiftClassC: NSObject {
public var classA: SwiftClassA
public init(classA: SwiftClassA) {
self.classA = classA
}
public func cFunction(testA: Double,
testB: Double) {
let classB = SwiftClassB(testA: testA,
testB: testB)
// do something
}
public func cFunction() {
// do something
return
}
}
The other thing to be aware of is if your project doesn't compile, you won't get the swift header file that Objective-C reads from:
#import <ProjectA-Swift.h>
#import <ProjectC-Swift.h>
In the Objective-C code I've converted, I occasionally run into issues with the import declaration where it wants @import "ProjectA-Swift.h"
instead of the one you used, so you could try playing around with that, as well.
Lastly, might want to open up your Objective-C header and click the little 4 square thingie at the upper left corner and click "Swift 5 generated interface", which, when clicked, will give you something that looks very similar to a protocol declaration...there won't be methods and vars, but it'll show you what the compiler is expecting from a method signature standpoint.
If you encounter a situation where Objective-C wants a specific signature for a method, you can use an alias in front of the method that doesn't match. An alias would look something like this:
@objc(myMethod:parameter1:parameter2)
Upvotes: 0
Reputation: 54716
You need to mark the classes as @objc
too, it isn't enough to mark their methods as @objc
.
@objc public class SwiftClassA: NSObject {
@objc public init() {
// do something
}
@objc public func aFunction() {
// do something
}
}
@objc public class SwiftClassB: NSObject {
...
}
@objc public class SwiftClassC: NSObject {
...
}
Upvotes: 2