简体   繁体   中英

ObjC protocol Implementation in Swift

Ok here is the big problem. I had a library written in ObjC( this ). There we had a defined protocol. When I tried to use it in swift file I get constantly:

Type "XXX" does not conform to protocol "XXX"

To simplify things I made up a test project - it should be created as Swift project.

Then create ObjC header file(I called it StupidProtocol.h) with following protocol inside(please note each name and value to exactly match the given including uppercase/lowercase):

@protocol MyProtocol <NSObject>

- (NSString *)getAxisLabel:(id)axis Value:(CGFloat)value;

@end

In bridging header:

#import "StupidProtocol.h"

And then back in Swift file:

class ViewController: UIViewController, MyProtocol
{
    func getAxisLabel(axis: AnyObject!, value: CGFloat) -> String! {
        return ""
    }
}

And baam we got this error again even though auto-complete finishes the getAxisLabel function for me.

I strongly suspect that the problem is with argument "value" and it's function parameter "Value".

Any help will be highly appreciated.

EDIT

Please note that this library is not technically mine, so I cannot change it. I need a way to use it in Swift without changing it's original declaration. My example is only to simplify my problem.

WHAT I TRIED

I have tried following scenarios with no success:

'has different arguments name from those required by protocol' error

func getAxisLabel(axis: AnyObject!, Value value: CGFloat) -> String! {
    return ""
}

'has different arguments name from those required by protocol' error

func getAxisLabel(axis: AnyObject!, Value: CGFloat) -> String! {
    return ""
}

'type does not conform to protocol'

func getAxisLabel(axis: AnyObject!, Value: CGFloat) -> NSString! {
    return ""
}

SOLUTION

See accepted answer

I don't know if this is a bug or not. The Objective-C protocol method

- (NSString *)getAxisLabel:(id)axis Value:(CGFloat)value;

(with uppercase "V" in Value: ) is mapped to Swift as

func getAxisLabel(axis: AnyObject!, value: CGFloat) -> String!

(with lowercase "v" in value: ), but none of

func getAxisLabel(axis: AnyObject!, value: CGFloat) -> String! { }
func getAxisLabel(axis: AnyObject!, Value: CGFloat) -> String! { }

is accepted by the compiler to satisfy the protocol requirement.

As a workaround, you can annotate the method with an explicit Objective-C selector name:

class ViewController: UIViewController, MyProtocol
{
    @objc(getAxisLabel:Value:)
    func getAxisLabel(axis: AnyObject!, value: CGFloat) -> String! {
        return ""
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM