2
votes

Just trying to get started with Swift and hit the following issue when upgrading to Swift 1.2:

@protocol MyObjcProtocol <NSObject>
@optional
@property (copy) NSString *optionalString;
- (void) optionalMethod;
@end

...

class MySwiftClass: NSObject {}

extension MySwiftClass: MyObjcProtocol {
  var optionalString: NSString {
    get { return "Foo" }
    set(newValue) { NSLog("Whatever") }
  }

  // No problem here
  func optionalMethod() {
    NSLog("Bar")
  }
}

The Swift extension implementing the Objc protocol doesn't compile with:

Objective-C method 'optionalString' provided by getter for 'optionalString' conflicts with optional requirement getter for 'optionalString' in protocol 'MyObjcProtocol'...

Objective-C method 'setOptionalString:' provided by setter for 'optionalString' conflicts with optional requirement setter for 'optionalString' in protocol 'MyObjcProtocol'...

So clearly the compiler doesn't realise I'm trying to implement the optionals from the protocol, and thinks I'm stomping on the protocol's expected ObjC symbols. The optional method func optionalMethod() compiles just fine, however. Remove @optional from the protocol and everything compiles just fine, but it's not always possible or desirable to do that as a solution.

So, how does one implement this? Trying to implement the expected ObjC methods explicitly doesn't work either:

func optionalString() {
  return "foo"
}
func setOptionalString(newValue: NSString) {
  NSLog("")
}

Hope someone can help! Thanks in advance!

3

3 Answers

3
votes

MyObjcProtocol protocol is translated to Swift as:

protocol MyObjcProtocol : NSObjectProtocol {

    optional var optionalString: String! { get set }
    optional func optionalMethod()
}

So you can just use String instead of NSString.

extension MySwiftClass: MyObjcProtocol {
    var optionalString: String {
        get { return "Foo" }
        set(newValue) { NSLog("Whatever") }
    }

    func optionalMethod() {
        NSLog("Bar")
    }
}
0
votes

I guess the problem is that the protocol requires a stored property because it's specified copy, but the swift extension cannot have storage for a property

0
votes

Optional properties in Objective C is equivalent to Optional Type in Swift. So it would translate like this:

var optionalString: String! // = false

in case it can be nil:

var optionalString: String? // = nil