0
votes

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.

2
Related (dupe?): Why can't a get-only property requirement in a protocol be satisfied by a property which conforms?. 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

2 Answers

0
votes

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?
}
0
votes

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?
}