Using an implementation of a Swift protocol within Obj-C

Gruntcakes

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?

Moshe

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.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How to expose existing property on Obj-C class using an extension protocol in Swift

Using Swift protocol default implementation in Kotlin Multiplatform

swift, objective-c protocol implementation

Conforming to an Obj-C protocol's property in Swift

Can not find Swift Protocol declaration in Obj-C class

Using Obj-C that relies on other Obj-C in Swift?

ObjC protocol Implementation in Swift

Calling a static Swift Method from within Obj-C

Using obj-c typedef in Swift

Using Obj-C completion block in Swift

How to use swift protocol implementation in Objective-C?

Accessing Swift protocol property implemented in an Obj-C class from another Swift class

Using a Swift protocol in Objective-C

Swift - Default Implementation of protocol functions in another protocol

Swift: Providing a default protocol implementation in a protocol extension

Overriding Obj-C-methods in Swift using Swift enums

Edit css file in swift/obj c without using javascript

Properly using Obj-C library in Swift project

Using an Obj-C sub-project in a Swift application

Swift 2 - completion block syntax when using in Obj-C

Swift using generic in protocol

Is there a way to know that method is protocol implementation in Swift?

Swift protocol with generic method: invalid redeclaration of implementation

Swift protocol default implementation for optional readonly variables

Implementation of Functor protocol with associated type (Swift)

How the call the default implementation code in protocol in swift?

Extending a Protocol property to provide a default implementation in Swift

Default implementation of protocol extension in Swift not working

Swift: Store Type of implementation of Protocol in static var of protocol extension