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.
source to share
No one has answered this question yet
Check out similar questions: