Game Center匹配报错:被主机取消,求技术解决方案
Hey there! Let's break down your Game Center issues step by step—first the missing data reception, then those confusing ICE error logs.
1. Fix the Core Issue: No Data Received
The biggest problem here is almost certainly that you haven't set the GKMatch delegate on your game view controller. You've implemented the GKMatchDelegate methods, but if the match doesn't know to send events to your ViewController instance, those callbacks will never fire.
Fix Steps:
- In your
ViewController'sviewDidLoadormatchStartmethod, add this line right after you confirm the match exists:
For example, update yourmatch?.delegate = selfmatchStartfunction:func matchStart() { guard let match = match else { print("ERROR: Match is nil!") return } match.delegate = self // This is critical! let localPlayerID = GKLocalPlayer.localPlayer().playerID let initialTurn = "initRand,\(localPlayerID ?? \"ERROR: NO ID\"),\(aTaps),0,0" let turnData = initialTurn.data(using: .utf8) print("Sending String: \(initialTurn)") sendData(turnLog: turnData!) } - Also, double-check that your
matchproperty inViewControlleris declared as a strong reference (not weak), otherwise the match object might get deallocated before you can receive data:var match: GKMatch! // Or var match: GKMatch? with proper unwrapping
2. Address the ICE Connection Errors
The logs like RemoveNominatedCandidatePair:994 failed with invalid index input are related to Game Center's underlying ICE (Interactive Connectivity Establishment) framework, which handles peer-to-peer connections. These are common in the sandbox environment, but they can sometimes indicate a partial or unstable connection.
Things to Try:
- Wait for full player connection: Instead of sending data immediately when the view loads, wait until you get confirmation that all remote players are connected via the
match(_:player:didChange:)delegate method. Update that method to track player states:
Then remove thepublic func match(_ match: GKMatch, player: GKPlayer, didChange state: GKPlayerConnectionState) { print("Player \(player.displayName) changed state to \(state.rawValue)") if state == .connected { // Check if all players are connected before sending initial data let connectedPlayers = match.players.filter { player in match.connectionState(for: player) == .connected } if connectedPlayers.count == match.players.count { print("All players connected—sending initial data") matchStart() // Or just send your initial data here } } }matchStart()call fromviewDidLoadso you only send data once everyone is fully connected. - Test on physical devices: Game Center peer-to-peer matches often have issues on simulators, especially with connectivity. Try testing on two real iOS devices logged into different Game Center sandbox accounts.
- Reset Game Center sandbox: Sometimes sandbox state gets stuck. Go to Settings > Game Center > Sandbox > Log Out, then log back in with your test accounts.
3. Check for Other Potential Issues
- Verify match handoff: In your
didFind matchmethod, make sure you're dismissing the matchmaker properly and not leaving any dangling references. Your current code looks okay, but ensure you're not retaining the matchmaker view controller unnecessarily. - Check data sending reliability: You're using
GKMatchSendDataMode.reliable, which is good for game state data, but if the connection is unstable, reliable mode might queue data until the connection is fixed. The ICE errors could be causing this queue to back up.
Once you fix the delegate issue, you should start seeing the RECEIVED DATA 8.0 logs in your console. If the ICE errors persist but data is flowing, they're likely just sandbox noise and shouldn't affect production builds.
内容的提问来源于stack exchange,提问作者dvd.Void

