I am trying to implement a real-time match in GameCenter using GameKit and SpriteKit.
This is my scene:
This is my GameCenterManager class:
So, basically this is what happens.
Any help would be greatly appreciated!
This is my scene:
Code Block class IntroScene: SKScene, GameCenterManagerDelegate { var gameCenterManager: GameCenterManager? override func didMove(to view: SKView) { GameCenterManager.manager.delegate = self <other code> } override func didChangeSize(_ oldSize: CGSize) { super.didChangeSize(oldSize) GameCenterManager.manager.authenticatePlayer() } func didChangeAuthStatus(isAuthenticated: Bool) { ...Enabling the Button to play in GameCenter } func presentGameCenterAuth(viewController: UIViewController?) { guard let vc = viewController else {return} self.view!.window?.rootViewController?.present(vc, animated: true) } func presentMatchmaking(viewController: UIViewController?) { guard let vc = viewController else {return} self.view!.window?.rootViewController?.present(vc, animated: true) } ->> Problem here. Never gets called func presentGame(match: GKMatch) { print("....INTROSCENE: DELEGATE PRESENT_GAME CALLED......") ... Presenting a new scene } }
This is my GameCenterManager class:
Code Block final class GameCenterManager : NSObject, GKLocalPlayerListener { static let manager = GameCenterManager() weak var delegate: GameCenterManagerDelegate? var maxPlayers = 2 var match: GKMatch? static var isAuthenticated: Bool { return GKLocalPlayer.local.isAuthenticated } override init() { super.init() } func authenticatePlayer() { GKLocalPlayer.local.authenticateHandler = { gcAuthVC, error in self.delegate?.didChangeAuthStatus(isAuthenticated: GKLocalPlayer.local.isAuthenticated) if GKLocalPlayer.local.isAuthenticated { GKLocalPlayer.local.register(self) } // If the User needs to sign to the Game Center else if let vc = gcAuthVC { self.delegate?.presentGameCenterAuth(viewController: vc) } else { print(">>>>> Error authenticating the Player! \(error?.localizedDescription ?? "none") <<<<<") } } } func presentMatchmaker() { guard GKLocalPlayer.local.isAuthenticated else { return } let request = GKMatchRequest() request.minPlayers = 2 request.maxPlayers = 6 request.inviteMessage = "Would you like to play?" guard let vc = GKMatchmakerViewController(matchRequest: request) else { return } vc.matchmakerDelegate = self delegate?.presentMatchmaking(viewController: vc) } // THIS IS WORKING... func player(_ player: GKPlayer, didAccept invite: GKInvite) { print("-----player -- did accept invite-------\(player.displayName)") guard let vc = GKMatchmakerViewController(invite: invite) else { return } vc.matchmakerDelegate = self self.gameCenterViewController?.present(vc, animated: true, completion: nil) } func player(_ player: GKPlayer, didRequestMatchWithRecipients recipientPlayers: [GKPlayer]) { print("didRequestMatchWithRecipients") } func player(_ player: GKPlayer, matchEnded match: GKTurnBasedMatch) { print("match ended") } func player(_ player: GKPlayer, wantsToQuitMatch match: GKTurnBasedMatch) { print("wants to quit match") } } extension GameCenterManager: GKMatchmakerViewControllerDelegate { // THIS IS NOT WORKING -( func matchmakerViewController(_ viewController: GKMatchmakerViewController, didFind match: GKMatch) { print("-----matchmakerVC did find match-------") viewController.dismiss(animated: true) match.delegate = self delegate?.presentGame(match: match) } func matchmakerViewControllerWasCancelled(_ viewController: GKMatchmakerViewController) { print("matchmakerVC was cancelled") viewController.dismiss(animated: true) delegate?.matchmakingCancelled() } func matchmakerViewController(_ viewController: GKMatchmakerViewController, didFailWithError error: Error) { viewController.dismiss(animated: true) delegate?.matchmakingError(error: error) } } extension GameCenterManager: GKMatchDelegate { func match(_ match: GKMatch, didReceive data: Data, forRecipient recipient: GKPlayer, fromRemotePlayer player: GKPlayer) { // HANDLE DATA } func match(_ match: GKMatch, didReceive data: Data, fromRemotePlayer player: GKPlayer) { //HANDLE DATA } func match(_ match: GKMatch, player: GKPlayer, didChange state: GKPlayerConnectionState) { print("-----match did change state") guard match == self.match else { return } switch state { case .connected where self.match != nil : print("-----MATCH DID CHANGE STATE CONNECTED-----") case .disconnected: print("-----MATCH DID CHANGE STATE DISCONNECTED-----") default: break } } func match(_ match: GKMatch, didFailWithError error: Error?) { print("-----match did fail with error") } }
So, basically this is what happens.
Player 1 starts the game. The player gets successfully authenticated.
I invite Player 2 to join the game. The invitation is sent to Player 2's device.
Player 2 accepts the game (printing player did accept invite).
Any help would be greatly appreciated!