I'm building a game using Game Center's turn based matches.
I want to display a list of all the available matches. I've tried using loadMatchesWithCompletionHandler()
, but the array of games returns as nil
, and the error also returns as nil
. There are some ongoing matches.
This is what I have so far:
func authenticateLocalUser() {
if !gameCenterAvailable { return }
let player = GKLocalPlayer.localPlayer()
if player.authenticated == false {
player.authenticateHandler = {(viewController, error) -> Void in
if viewController != nil && self.presentingViewController != nil
{
self.presentingViewController!.presentViewController(viewController!, animated: true, completion: {
GKLocalPlayer.localPlayer().registerListener(self)
GKTurnBasedMatch.loadMatchesWithCompletionHandler({games, error in
print(games)
if games != nil {
print(games!.count)
}else {
print(error)
}
})
})
} else {
if player.authenticated == true {
GKLocalPlayer.localPlayer().registerListener(self)
GKTurnBasedMatch.loadMatchesWithCompletionHandler({games, error in
print(games)
if games != nil {
print(games!.count)
}else {
print(error)
}
})
}
}
}
} else {
print("already authenticated")
}
}
I even get nil
when creating a new match (it will print the match I just created, though):
func findMatchWith(minPlayers: Int, maxPlayers: Int) {
if !gameCenterAvailable { return }
let request = GKMatchRequest()
request.minPlayers = minPlayers
request.maxPlayers = maxPlayers
request.defaultNumberOfPlayers = 2
GKLocalPlayer.localPlayer().loadFriendPlayersWithCompletionHandler({players, error in
if error != nil {return}
request.recipients?.append(players![0])
GKTurnBasedMatch.findMatchForRequest(request, withCompletionHandler: { match, error in
if error != nil {
print(error?.localizedDescription)
return
}
print(match)
GKTurnBasedMatch.loadMatchesWithCompletionHandler({games, error in
print(games)
if games != nil {
print(games!.count)
}else {
print(error?.localizedDescription)
}
})
})
})
}
It's a little hard to tell from the snippet you've shown. Things to double check:
You assume if
.authenticated
is YES then you are logged in. Unfortunately, that's not always true. GC will report YES in conditions where it can't talk to GC servers but is using cached data from a prior session. (Usually, though, you'll actually get an error about not being authenticated when you attempt to load matches while in this state)You assume if the VC is nil, then you are authenticated. That's not always true, either. If an error is set, the VC will also be nil. Always check the value of the error first thing in the authentication handler. (I don't think this contributes to your problem now, though, because again: you should get an error if you try to load matches when you're actually not authenticated)
If you're interested, you can see an example of my authentication handler, which catches a variety of edge cases and failures, at https://stackoverflow.com/a/37216566/1641444
It wasn't the code. It was how the game was set up in iTunes Connect. I needed to do this:
Later, I will try to delete the leaderboard, and see if it still works. The actual app won't have a leaderboard.
My confusion was because I wasn't getting the "unrecognized game" error, and I was able to create matches, play turns, list player's friends, but not list matches.