15

In Objective-C, you could define a type as being of a given class and implementing a protocol:

- (UIView <Protocol> *)someMethod;

This would tell that the value returned by someMethod was a UIView implementing a given protocol Protocol. Is there a way to enforce something similar in Swift?

Kamchatka
  • 3,597
  • 4
  • 38
  • 69
  • 3
    Similar question here: http://stackoverflow.com/questions/25767156/swift-property-conforming-to-a-specific-class-and-in-the-same-time-to-multiple?rq=1 – Martin R Sep 13 '14 at 17:54
  • similar here as well http://stackoverflow.com/questions/26401778/swift-how-can-i-declare-a-variable-of-a-specific-type-that-conforms-to-one-or-m – Daniel Galasko Sep 07 '15 at 15:17

1 Answers1

10

You can do it like this:

protocol SomeProtocol {
  func someMethodInSomeProtocol()
}

class SomeType { }

class SomeOtherType: SomeType, SomeProtocol {
  func someMethodInSomeProtocol() { }
}

class SomeOtherOtherType: SomeType, SomeProtocol {
  func someMethodInSomeProtocol() { }
}

func someMethod<T: SomeType where T: SomeProtocol>(condition: Bool) -> T {
  var someVar : T
  if (condition) {
    someVar = SomeOtherType() as T
  }
  else {
    someVar = SomeOtherOtherType() as T
  }

  someVar.someMethodInSomeProtocol()
  return someVar as T
}

This defines a function that returns an object of type 'SomeType' and protocol 'SomeProtocol' and returns an object that adheres to those conditions.

  • Thanks. In that case, in someMethod if I do: `var v: T; v = MyView()`, I'm getting an error 'MyView is not convertible to T' even though MyView is a `class MyView : UILabel, Protocol`. – Kamchatka Sep 14 '14 at 09:36
  • If you add 'as T' to the end of the return it works. I'll update the answer. –  Sep 14 '14 at 12:15
  • Thanks, that's better. I'm still having the following problem in implementing the method: `func someMethod() -> T { var someVar: T someVar.someMethodInSomeProtocol() <-- ERROR "T does not have a member named 'someMethodInSomeProtocol' return someVar as T }` – Kamchatka Sep 14 '14 at 23:15
  • Does your protocol actually define 'someMethodInSomeProtocol()'? If I have that define in the protocol and implemented in the class then I don't get your error. –  Sep 14 '14 at 23:22
  • Yes, it does. But in my case someVar is of type T `func someMethod(condition: Bool) -> T { var someVar : T if (condition) { someVar = SomeOtherType() as T } else { someVar = SomeOtherOtherType() as T } someVar.someMethodInSomeProtocol() return someVar as T }` – Kamchatka Sep 15 '14 at 08:03
  • as described in the other thread (http://stackoverflow.com/questions/25767156/swift-property-conforming-to-a-specific-class-and-in-the-same-time-to-multiple) it seems that using a where clause solves the issue. `func someMethod()` is not the same as `func someMethod()`. I don't understand why the latter doesn't work. – Kamchatka Sep 15 '14 at 09:18
  • Yeah, I found that after some digging. The interesting thing is when I do that I crash my playground. I'll update my answer with what seems to work and file a bug on the crash. –  Sep 15 '14 at 13:40