Basically, the issue stems from loss of internet connection during a turn: at the end of a turn we save the state of the game board (locally, to PlayerPrefs), and use an End Turn method to communicate to Game Center that the turn is over.
If there’s no internet connection, the game state is saved but the end of turn message never gets sent (Android is awesome in the sense that end of turn messages are cached if the user has no internet connection, and sent when there is).
That is awesome, if it handles all network errors and not just lack of internet.
So my question here is really, how do you gracefully handle a loss of internet connection? The only solution we have is to test for a connection prior to saving/ending the turn and present a pop-up advising the player to connect to the internet (otherwise, their turn is held in that state).
This one is enormously tricky with Game Center, because it has no guaranteed delivery.
First, I would not check for any specific error, because you can have anything at all go wrong during networking. (“No internet” might be worth a special test just because the player can deal with it by turning on WiFi or whatever, but it’s the least of your problems.)
Basically, you need to send the turn to Game Center and check for an error when your completion handler is called. If there’s failure, you need to do your own saving, and then send the update again later.
The problem is, you can get false negatives. Did you get a timeout because your network was so slow or noisy that the packet could not be delivered to Game Center? Or was the timeout because the “yes, turn received” acknowledgement from Game Center timed out? This is critical because the other player will have gotten the turn, and may have sent their own by the time you get to repost. So you also need some sort of logic to handle posting a stale turn.
To test your code, you’ll want to use the Network Link Conditioner (enable this in the Developer settings on the device). This lets you simulate a terrible network. Just be sure to disable it when you want to actually do anything (it’s all too easy to forget and wonder what’s wrong with your phone).