0

According to the documentation, I should implement the GKTurnBasedEventListener protocol's player(_:receivedTurnEventFor:didBecomeActive:) method to receive turn-based event information.

Although it's documented as GKTurnBasedEventListener, Apple now recommends that we implement the GKLocalPlayerListener protocol instead of several separate protocols including GKTurnBasedEventListener.

From the docs:

Adopt the GKLocalPlayerListener protocol to handle a variety of Game Center events instead of the individual GKChallengeListener, GKInviteEventListener, GKSavedGameListener, and GKTurnBasedEventListener protocols. Then implement the player(_:receivedTurnEventFor:didBecomeActive:) and other GKTurnBasedEventListener protocol methods to handle turn-based events that occur throughout a match.

So, I've implemented GKLocalPlayerListener.

At first, I was using the default Game Center interface -- and player(_:receivedTurnEventFor:didBecomeActive:) was called as expected (when the user started a new match, for example).

However, now that I'm using my own custom interface, the method is no longer called, ever. It's not called on the Simulator, and it's not called on device.

So, here's what I'm doing:

  1. Set up the GKLocalPlayerListener protocol:
class GameCenterMatches: UIViewController, GKLocalPlayerListener {
    ...
}
  1. Add the player(_:receivedTurnEventFor:didBecomeActive:) method to the class:
func player(_ player: GKPlayer, receivedTurnEventFor match: GKTurnBasedMatch, didBecomeActive: Bool) {
    ...
}
  1. Immediately after authenticating with Game Center, register the class with the local player (GameCenterAuth.player is GKLocalPlayer.local, and SceneDelegate.gameCenterMatches is GameCenterMatches()):
GameCenterAuth.player.register(SceneDelegate.gameCenterMatches)

As an example of something I believe should trigger player(_:receivedTurnEventFor:didBecomeActive:), here's how I'm creating new matches:

let request = GKMatchRequest()
//Configure the request

GKTurnBasedMatch.find(for: request) { match, error in
    ...
}

Question: Why isn't player(_:receivedTurnEventFor:didBecomeActive:) being called for my custom interface events, and how can I make it work?

West1
  • 1,430
  • 16
  • 27
  • 1
    you'll find that lots of things in gamekit and game center are implemented in a mysterious way and don't always reflect the documentation. here are two things to try: (1) in your `GKTurnBasedMatch.find` completion closure, inspect who is `currentParticipant` and have them call `gkTurnBasedMatch.endTurn` to explicitly end the turn. (2) call `gkTurnBasedMatch.sendReminder` immediately after ending a turn. i found that in several cases network events won't push to recipient unless you follow it up w/ a reminder – Fault Apr 03 '22 at 17:46
  • also [this thread](https://stackoverflow.com/questions/34452098/gamecenter-ios-9-gamecenter-gklocalplayerlistener-methods-not-called) is old but i found it useful, including this [linked project](https://github.com/mhatzitaskos/TurnBasedSkeleton) – Fault Apr 03 '22 at 17:49

0 Answers0