0

How to confirm to protocols that declares properties of other protocols in Swift?

There is a protocol GKGameModel in which its implementers need to have a properties conforming to a protocol

public protocol GKGameModel {
    // ...
    public var players: [GKGameModelPlayer]? { get }
    public var activePlayer: GKGameModelPlayer? { get }
    // ...

}

public protocol GKGameModelPlayer {
    // ...
}

Now, suppose I have a class Player and GameModel that conforms to the above protocols

class Player : NSObject, GKGameModelPlayer  {
    //...
}


class GameModel : NSObject, GKGameModel  {
    //...
    public var players: [Player]? 
    public var activePlayer: Player?
}

Now the above code doesn't compile and the error messages (among others) were:

protocol requires property 'activePlayer' with type 'GKGameModelPlayer?'; do you want to add a stub?
candidate has non-matching type 'Player?'

However the Player class conforms to protocol GKGameModelPlayer, hence it should confirm just fine. How can I get this to compile?

Strangely Objective-C deals with this just fine – take a look at the FourInARow example code which does something like this.

Hamish
  • 78,605
  • 19
  • 187
  • 280
adib
  • 8,285
  • 6
  • 52
  • 91
  • 1
    Related (dupe?): [Why can't a get-only property requirement in a protocol be satisfied by a property which conforms?](http://stackoverflow.com/q/42561685/2976878). There's no real reason why this shouldn't be possible, as a `[Player]?` is convertible to a `[GKGameModelPlayer]?` and a `Player?` is convertible to a `GKGameModelPlayer?` – the compiler just doesn't support it yet. – Hamish Mar 25 '17 at 10:11

2 Answers2

0

The protocol requires that the properties be typed exactly as shown. In other words, an array of GKGameModelPlayers and a single optional GKGameModelPlayer?. If your Player type conforms to the protocol, then an array of Players can be passed to the protocol property if casted / typed as [GKGameModelPlayer].

But the requirement here is not, for example, an activePlayer property that has a type that conforms to GKGameModelPlayer, but rather an activePlayer property that references an instance that it typed as / cast as a GKGameModelPlayer.

I.e. this would fix the error:

class GameModel : NSObject, GKGameModel  {
    //...
    public var players: [GKGameModelPlayer]? 
    public var activePlayer: GKGameModelPlayer?
}
Daniel Hall
  • 13,457
  • 4
  • 41
  • 37
0

players and activePlayer property has a type that conforms to GKGameModelPlayer. So just change it to GKGameModelPlayer type instead of Player

class GameModel : NSObject, GKGameModel  {
    //...
    public var players: [GKGameModelPlayer]? 
    public var activePlayer: GKGameModelPlayer?
}
Vinoth Vino
  • 9,166
  • 3
  • 66
  • 70