3

I am quite new to Swift, started developing my own app recently. I've been trying to implement the Game Center multiplayer. The current structure of my project is (standard game center structure):

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

The issue I am facing it's at the very early stages of the multiplayer game generation. On the GameViewController, I have the following code to trigger the 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 triggered above is as follows:

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 the 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 start, as soon as the GKMatchmakerViewController is dismissed, the app crashes in the matchmakerViewController method that does 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 spotted that the exact line that is causing the problem above is the following:

    _match.delegate = self

The error that 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 instance 0x17047a600 2017-07-12 19:15:47.507642+0100 xxx[2653:492023] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[xxx.GameKitHelper match:didReceiveData:fromPlayer:]: unrecognized selector sent to instance 0x17047a600'

Any ideas what could be causing this issue? I've tried everything.

halfer
  • 19,824
  • 17
  • 99
  • 186

0 Answers0