2

In my iOS turn based match, I'm trying to receive notifications and to get the

public func player(_ player: GKPlayer, receivedTurnEventFor match: GKTurnBasedMatch, didBecomeActive: Bool)

to be called, with no success.

I register my view model to the local player

 GKLocalPlayer.localPlayer().register(self)

and I would expect that to fire after the other player executes

func endTurn(withNextParticipants nextParticipants: [GKTurnBasedParticipant], turnTimeout timeout: TimeInterval, match matchData: Data, completionHandler: ((Error?) -> Swift.Void)? = nil)

but no success.

If I force a reload of the matchData then I will get the data the second player just submitted. So the endTurn works correctly.

Is there something I'm doing wrong?

Update: So I create a new project, copied all my files over, in the capabilities only Game Center was enabled.

When developing it was working perfect, I had two devices attached (with different apple IDs). Notifications were working and Turnbasedlistener was firing.

As soon as I released it for internal testing it stopped working!!!

Apostolos
  • 409
  • 3
  • 13
  • Have you double-checked your application allows push notifications under "settings"? If a user decided not to enable push notifications, "receivedTurnEventFor" won't be called. – Erik W Jun 25 '17 at 00:06
  • Yes I did, Allow push notifications is enabled (Badges) – Apostolos Jun 25 '17 at 14:59
  • So I create a new project, copied all my files over, in the capabilities only Game Center was enabled. When developing it was working perfect, I had two devices attached (with different apple IDs). Notifications were working and Turnbasedlistener was firing. As soon as I released it for internal testing it stopped working!!! – Apostolos Jun 26 '17 at 22:05

2 Answers2

1

I had very similar issue. My solution was to manually recheck my status while waiting for my turn. FIrst, I defined global variable var gcBugTimer: Timer

In endTurn(withNextParticipants:turnTimeOut:match:completionHan‌​dler:) completion handler:

let interval = 5.0
self.gcBugTimer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(self.isMatchActive), userInfo: nil, repeats: true)
self.gcBugTimer.tolerance = 1.0

Code above also should be called in case when a player is joying to a new match and other player in a turn.

Then timer method:

func isMatchActive() {
  // currentMatch - global variable contains information about current match 
  GKTurnBasedMatch.load(withID: currentMatch.matchID!) { (match, error) in
    if match != nil {
      let participant = match?.currentParticipant
      let localPlayer = GKLocalPlayer.localPlayer()
      if localPlayer.playerID == participant?.player?.playerID {
        self.player(localPlayer, receivedTurnEventFor: match!, didBecomeActive: false)
      }
    } else {
      print(error?.localizedDescription ?? "")
    }
  }
}

And I add following code at the very beginning of player(_:receivedTurnEventFor:didBecomeActive):

if gcBugTimer != nil && gcBugTimer.isValid {
  gcBugTimer.invalidate()
}
1

What ended up working for me, was to test on an actual device, rather than in simulator. The receivedTurnEvents function doesn't seem to work in simulator.

Grigory's work around is great for testing with simulator.

D. Pratt
  • 444
  • 8
  • 15