Zhenlei Cai
Zhenlei Cai

Reputation: 123

Swift class trying to implement a Objective-C protocol failed with optional method conflict error

I have an Swift iOS project that uses the MLPAutoCompleteTextField library which is written in Objective-C. Here is the MLPAutoCompleteTextFieldDataSource protocol my Swift class is trying to implement:

@protocol MLPAutoCompleteTextFieldDataSource <NSObject>
@optional
- (void)autoCompleteTextField:(MLPAutoCompleteTextField *)textField
  possibleCompletionsForString:(NSString *)string
             completionHandler:(void(^)(NSArray *suggestions))handler;


- (NSArray *)autoCompleteTextField:(MLPAutoCompleteTextField *)textField
  possibleCompletionsForString:(NSString *)string;

@end

Here is my Swift class:

class MyAutocompleteDataSource : NSObject, MLPAutoCompleteTextFieldDataSource {
    override func autoCompleteTextField(textField : MLPAutoCompleteTextField, 
possibleCompletionsForString : String)
                    -> Array<String>  {
        return nil
    }
}

After compiling, these two errors are reported:

Error:(17, 23) method does not override any method from its superclass

Error:(17, 23) Objective-C method 'autoCompleteTextField:possibleCompletionsForString:' provided by method 'autoCompleteTextField(:possibleCompletionsForString:)' conflicts with optional requirement method 'autoCompleteTextField(:possibleCompletionsForString:)' in protocol 'MLPAutoCompleteTextFieldDataSource'

Really appreciate it if you could explain not only how to fix this but point out some general rules or references on how to map various types (Array, callback etc) when implementing a Obj-C protocol in Swift.

Upvotes: 1

Views: 236

Answers (2)

Pierre Oleo
Pierre Oleo

Reputation: 1209

For the first error, override is not needed when implementing a protocol method, only when reimplementing the method from a superclass

For the second error, in the protocol, the method returns an NSArray which is bridged as [AnyObject], not [String]

That would give

@objc func autoCompleteTextField(textField: MLPAutoCompleteTextField, possibleCompletionsForString string: String) -> Array<AnyObject> {
       return []
 }

If you really are sur the array will only contain strings you could instead change the protocol to the following, the you just have to remove the override keyword

- (NSArray <NSString *> *)autoCompleteTextField:(MLPAutoCompleteTextField *)textField
  possibleCompletionsForString:(NSString *)string;

Note that returning nil will not work as you return Array not Array?. If you really expect to return nil you need to add nullability to the return type Array?

You can replace Array by [String] if your prefer shorter lines

Upvotes: 3

Vahan Babayan
Vahan Babayan

Reputation: 723

Try this

override func autoCompleteTextField(textField : MLPAutoCompleteTextField, possibleCompletionsForString string : String)

Upvotes: 0

Related Questions