How to accept an invitation to Game Center

I am trying to implement invitations to Game Center, and there is one thing that I donโ€™t understand. Ok, I sent an invitation from one device to another. Then I have a UIAlertView on the receiver that asks me that I would like to accept or decline the invitation. when I accept it, it is processed as follows:

[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) { // Insert application-specific code here to clean up any games in progress. if (acceptedInvite) { GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:acceptedInvite] autorelease]; mmvc.matchmakerDelegate = self; [presentingViewController presentModalViewController:mmvc animated:YES]; } else if (playersToInvite) { GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease]; request.minPlayers = 2; request.maxPlayers = 4; request.playersToInvite = playersToInvite; GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease]; mmvc.matchmakerDelegate = self; [presentingViewController presentModalViewController:mmvc animated:YES]; } }; 

Ok, that's great, but what's next? the sending device is obviously waiting for some standard type of response, because it also shows a warning informing me that some invitations have not yet received an answer if I click "Play Now".

So how can I accept the invitation? What data (and how) should I send back? And what exactly should I do on the receiver side? Should the game begin immediately after clicking Accept, or should I release AlertView first and then click Play Now?

The Ray Wenderlich tutorial says that I have to choose the second method, but when you release the warning and click "Play Now", it turns out that the sending device is still waiting for an answer and I donโ€™t know that I already accepted the invitation. if I click "Play Now", then, as I said above, it shows a warning saying that the application is waiting for a response. Therefore, if you have ever done this, please explain to me what to do. Thank you

+6
source share
3 answers
  • I register for an invitation as soon as the game loads and calls a delegate when I receive an invitation
  • So inviteReceived calls the creator of the match to reject the game of the central controller and create a match
  • And finally, when a match is found, the connectionStatusChanged method takes care of representing all the views and players and so on.

Here is the code:

I register invitations as soon as the game is loaded, and call the delegate when I receive the invitation:

 - (void)registerInvites { [GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) { self.pendingInvite = acceptedInvite; self.pendingPlayersToInvite = playersToInvite; [delegate inviteReceived]; }; } 

So, inviteReceived calls the creator of the match to reject the game center controller and create a match:

 - (void)inviteReceived { [[GCMultiplayerHelper sharedInstance] findMatchWithMinPlayers:2 maxPlayers:2 viewController:(UIViewController*)[self.superview nextResponder] delegate:self]; } - (void)findMatchWithMinPlayers:(int)minPlayers maxPlayers:(int)maxPlayers viewController:(UIViewController *)viewController delegate:(id<GCMultiplayerHelperDelegate>)theDelegate { if (!gameCenterAvailable) return; matchStarted = NO; self.match = nil; self.presentingViewController = viewController; delegate = theDelegate; [presentingViewController dismissModalViewControllerAnimated:YES]; GKMatchmakerViewController *mmvc; if (pendingInvite != nil) { mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:pendingInvite] autorelease]; } else { GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease]; request.minPlayers = minPlayers; request.maxPlayers = maxPlayers; request.playersToInvite = pendingPlayersToInvite; mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease]; } mmvc.matchmakerDelegate = self; [presentingViewController presentModalViewController:mmvc animated:YES]; self.pendingInvite = nil; self.pendingPlayersToInvite = nil; } 

And finally, when a match is found, the connectionStatusChanged method will take care of presenting all the game representations, players and the start of the match:

 - (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)theMatch { self.match = theMatch; match.delegate = self; if (!matchStarted && match.expectedPlayerCount == 0) { NSLog(@"Ready to start match! - didFindMatch"); [presentingViewController dismissModalViewControllerAnimated:YES]; [self.delegate connectionStatusChanged:CONNECTIONSUCCESS]; } } 
+5
source

I successfully completed the match of the online game center after the lessons of Ray. The answer to your question: you do not need to send anything to the host device. When you call the line: GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease]; matchMakerVController processes the connection. However, you must write an ASAP prompt handler, preferably in a method with a modified authentication. See My:

 -(void) authenticationChanged { if ([GKLocalPlayer localPlayer].isAuthenticated && !userAuthenticated) { NSLog(@"Authentication changed: player authenticated."); userAuthenticated = TRUE; [self sendUnsentScores]; [GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite){ NSLog(@"Invite"); if([AppDelegate mainMenuController].presentedViewController!=nil) { [[AppDelegate mainMenuController] dismissViewControllerAnimated:NO completion:^{ }]; } // if we're not on the main menu, or another game is going on. // this would be easier to do if you were using a navigation controller // where you'd just push the multiplayer menu etc. self.pendingInvite = acceptedInvite; self.pendingPlayersToInvite = playersToInvite; [[AppDelegate mainMenuController] presentViewController:[AppDelegate mainMenuController].multiGameMenu animated:NO completion:^{ // push the multiplayer menu [[AppDelegate mainMenuController].multiGameMenu duel:nil]; }]; }; } 

and this duel method, if you're interested. Very dirty code, but deal with it :)

 - (IBAction)duel:(id)sender { NSLog(@"duel"); if (presentingMenu.multiGameController==nil || presentingMenu.multiGame.gameInProgress==NO) { presentingMenu.multiGame=nil; presentingMenu.multiGameController=nil; MultiViewController *mvc = [[MultiViewController alloc] init]; //create game VC presentingMenu.multiGameController = mvc; //presenting menu is just the main menu VC // it holds this menu, and the game // objects. } if (presentingMenu.multiGame == nil) { presentingMenu.multiGame = [[MultiGame alloc] // similarly create the game object initWithViewController:presentingMenu.multiGameController]; //they both have pointers to each other (A loose, bad MVC). presentingMenu.multiGameController.game = presentingMenu.multiGame; [presentingMenu.multiGame startGame]; } if (presentingMenu.multiGameController.gameState==0) { //new game presentingMenu.multiGameController.game = presentingMenu.multiGame; [[GCHelper sharedInstance] findMatchWithMinPlayers:2 maxPlayers:2 viewController:self delegate:presentingMenu.multiGame]; // the GC magic happens here - it know about the invite. } else { [self presentViewController:presentingMenu.multiGameController animated:YES completion:^{ }]; } } 
+3
source

inviteHandler = ^ (GKInvite * acceptInvite, NSArray * playersToInvite) is deprecated now. See New way to register invitation notifications.

GKMatchMaker calls obsolete handler

+1
source

All Articles