Swift - GKMatchDelegate

I am completely new to Swift, recently started developing my application. I was trying to implement Game Center multiplayer. My project's current structure (standard play center structure):

  • GameViewController - UIViewController, GKGameCenterControllerDelegate
  • GameKitHelper - NSObject, GKGameCenterControllerDelegate, GKMatchmakerViewControllerDelegate, GKMatchDelegate
  • GameKitHelperDelegate - protocol (matchStarted, matchEnded, match)
  • MultiplayerNetwork - GameKitHelperDelegate (used to send and process messages)

A problem I ran into in the early stages of creating a multiplayer game. On GameViewController, I have the following code to start a multiplayer game:

    func playMultiGame(){
    var gameScene = GameSceneMultiPlayer(size:CGSize(width: 2048, height: 1536))

    let networkingEngine = MultiplayerNetworking()
    networkingEngine.delegate = gameScene
    gameScene.networkingEngine = networkingEngine
    GameKitHelper.SharedGameKitHelperInstance.findMatchWithMinPlayers(minPlayers: 2, maxPlayers: 2, viewController: self, delegate: networkingEngine)

    let skView = self.view as! SKView

    gameScene.scaleMode = .fill
    skView.presentScene(gameScene)        

}

      

The findMatchWithMinPlayers method above looks like this:

func findMatchWithMinPlayers(minPlayers:Int, maxPlayers:Int, viewController:UIViewController, delegate:GameKitHelperDelegate) {

    if(!_enableGameCenter) {
        return;
    }

    _matchStarted = false
    self._match = nil
    _delegate = delegate
    viewController.dismiss(animated: false, completion: nil)

    //GKmatch request
    let request = GKMatchRequest()
    request.minPlayers = minPlayers
    request.maxPlayers = maxPlayers

    let mmvc = GKMatchmakerViewController(matchRequest: request)
    mmvc?.matchmakerDelegate = self
    viewController.present(mmvc!, animated: true, completion: nil)
}

      

The method above is in GameKitHelper, which has the following methods:

class GameKitHelper : NSObject, GKGameCenterControllerDelegate, GKMatchmakerViewControllerDelegate, GKMatchDelegate {
var _enableGameCenter : Bool
var _matchStarted : Bool
var _match : GKMatch!
var _delegate : GameKitHelperDelegate?
var authenticationViewController: UIViewController?
var lastError : NSError?
var playersDict : NSMutableDictionary?

class var SharedGameKitHelperIntance:GameKitHelper {
    return _GameKitHelperSharedInstace
}

override init() {
    self._enableGameCenter = true
    self._matchStarted = false
    super.init()
}

func authenticateLocalPlayer() {
   [...]
}

func setAuthenticationViewController(authViewController:UIViewController!) {
   [...]     
}

func findMatchWithMinPlayers(minPlayers:Int, maxPlayers:Int, viewController:UIViewController, delegate:GameKitHelperDelegate) {
  [...]
}

func lookupPlayers() {
   [...]
}

/* Implementing delegate GKMatchmakerViewControllerDelegate methods */
func matchmakerViewControllerWasCancelled(_ viewController:GKMatchmakerViewController) {
    viewController.dismiss(animated: true, completion: nil)
    print("canceling multiplayer view")
    _delegate?.matchEnded()
}


func matchmakerViewController(_ viewController: GKMatchmakerViewController,
                              didFailWithError error: Error) {
    viewController.dismiss(animated: true, completion: nil)
    NSLog("Error finding match: %@", error.localizedDescription)
}

func matchmakerViewController(_ viewController: GKMatchmakerViewController,
                                       didFind match: GKMatch!) {

    viewController.dismiss(animated: true, completion: nil)
    match.delegate = self
    _match = match

    if(!_matchStarted && match.expectedPlayerCount==0) {
        NSLog("Ready to start match")
        self.lookupPlayers()
    }
}

/* Implementing delegate GKMatchDelegate methods */
func match(match: GKMatch!, didReceiveData data: NSData!, fromPlayer playerID: NSString!) {
    if(_match != match) {
        return
    }

    _delegate?.match(match: match, didReceiveData: data, fromPlayer: playerID)
}

func match(match: GKMatch!,  player: String!, didChangeState state: GKPlayerConnectionState) {

    if(_match != match) {
        return
    }

    switch(state) {
    case GKPlayerConnectionState.stateConnected:
        if(!_matchStarted && match.expectedPlayerCount == 0) {
            NSLog("Ready to start match!")
            self.lookupPlayers()
        }

    case GKPlayerConnectionState.stateDisconnected:
        NSLog("Player disconnected!")
        _matchStarted = false
        _delegate?.matchEnded()
    default:
        break
    }


}

func match(match: GKMatch!, connectionWithPlayerFailed:String!, withError error:NSError!) {

    if(_match != match) {
        return
    }
    NSLog("Failed to connect to player with error: %@", error.localizedDescription)
    _matchStarted = false
    _delegate?.matchEnded()

}

func match(match: GKMatch!, didFailWithError error: NSError!) {

    if(_match != match) {
        return
    }
    NSLog("Match failed with error: %@", error.localizedDescription)
    _matchStarted = false
    _delegate?.matchEnded()

}

func gameCenterViewControllerDidFinish(_ gameCenterViewController: GKGameCenterViewController)
{
    gameCenterViewController.dismiss(animated: true, completion: nil)
}

      

Once the two users have been paired and the game is ready to run, as soon as the GKMatchmakerViewController is fired, the application crashes in the matchmakerViewController method, which performs this action:

func matchmakerViewController(_ viewController: GKMatchmakerViewController,
                                       didFind match: GKMatch!) {

    viewController.dismiss(animated: true, completion: nil)
    _match.delegate = self
    _match = match

    if(!_matchStarted && match.expectedPlayerCount==0) {
        NSLog("Ready to start match")
        self.lookupPlayers()
    }
}

      

Through the exception breakpoint, I noticed that the exact line causing the problem above is as follows:

    _match.delegate = self

      

The error I am getting is the following:

2017-07-12 19: 15: 47.472473 + 0100 xxx [2653: 492023] - [xxx.GameKitHelper match: didReceiveData: fromPlayer:]: unrecognized selector sent to example 0x17047a600 2017-07-12 19: 15: 47.507642 + 0100 xxx [2653: 492023] *** Application terminated due to unmapped "NSInvalidArgumentException", reason: '- [xxx.GameKitHelper match: didReceiveData: fromPlayer:]: unrecognized selector posted in example 0x17047a600'

Any ideas what might be causing this problem? I've tried everything.

+3


source to share





All Articles