Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
290 views
in Technique[技术] by (71.8m points)

ios - 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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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 ""
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...