Search code examples
swiftprotocols

Two structs bind to a protocol with an optional variable error


I have two structs like this

struct LastKey:Equatable, MyProtocol {
  var id: UUID  
  let lowercase:String?

  var isValid:Bool {
    // calculate
  }
} 

struct FirstKey:Equatable, MyProtocol {
  var id: UUID
  let name:String?
}

protocol MyProtocol {
  var id:UUID { get set }
}

Then I decided to use this

func setLastKey(_ lastKey:MyProtocol) {
  let lastKey = LastKey()
  if lastKey.isValid { // do something }
}

But because lastKey is of type MyProtocol, and isValid is not on the protocol I have to add it as optional, because firstKey doesn't have this property.

If I change the protocol to

@objc protocol MyProtocol {
  var id:UUID { get set }
  @objc optional var isValid:Bool { get set }
}

then the structs whine with the following error:

Non-class type 'FirstKey' cannot conform to class protocol 'MyProtocol'
Non-class type 'LastKey' cannot conform to class protocol 'MyProtocol'

Solution

  • Instead of using optional and being forced to use @objc I would declare the protocol as

    protocol MyProtocol {
      var id:UUID { get set }
      var isValid:Bool { get }
    }
    

    Note that I removed set for the isValid property because it goes better with how you declare it in LastKey and it doesn’t make much sense that you can set it externally.

    And add a default implementation for those types that doesn’t need a custom logic

    extension MyProtocol {
        var isValid: Bool { true }
    }