I'm trying to implement a mediator sort of pattern with a mixture of Swift and Obj-C. The issue I'm facing is with how to deal with using the Swift protocol implementation classes from Obj-C. Check out the code to see what I mean:
The Swift protocol and implementation of it:
@objc public protocol TheProtocol {
func someMethod()
}
@objc public class SwiftClass: NSObject, TheProtocol {
public func someMethod() {
print("someMethod Swift")
}
}
The ObjC-implementation of the protocol:
#import "SwiftAndObjC-Swift.h"
@interface ObjCClass : NSObject <TheProtocol>
- (void) someMethod;
@end
@implementation ObjCClass
- (void) someMethod
{
NSLog(@"someMethod ObjC");
}
@end
My question is how is it possible to define some type in ObjC which is capable of referencing either a SwiftClass or an ObjCClass. For example this does not compile:
#import "SwiftAndObjC-Swift.h"
...
TheProtocol *p = [[ObjCClass alloc] init];
// Error: "Use of undeclared identifier TheProtocol"
This will compile:
@class TheProtocol
TheProtocol *p = [[ObjCClass alloc] init];
But not p can't be used:
@class TheProtocol
TheProtocol *p = [[ObjCClass alloc] init];
[p someMethod];
// Error: Receiver type "The Protocol" is a forward declaration"
(Adding casts to the assignment and/or method invocation doesn't help)
Any solutions?
In Objective-C, a protocol is not a type. You should declare your protocol-conforming class like so:
id<TheProtocol> p = [[ObjCClass alloc] init];
The reason why your forward declaration compiled is because that's what forward declarations do - they announce to the compiler that a class exists and that the linker will fill it in later in the build process.
(That's why changing to id p =...
works too.)
In Swift, we declare classes with something like:
class MyClass : Superclass, Protocol, AnotherProtocol { ... }
In Objective-C we use this:
@class MyClass : SuperClass <Protocol, AnotherProtocol>
// ...
@end
See the difference? In Swift, protocols and the superclass are mixed into the inheritance declaration, whereas Objective-C treats them very differently.
Protocols and Classes are treated slightly different across the two languages, thus used differently.
id
in ObjectiveC is analogous to AnyObject?
in Swift. An object which conforms to SomeProtocol
is obviously AnyObject
or id
in Objective-C.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With