7

I'm creating a real time matches game and I'm confused as to how to deal with game invitations? For instance, a player on one device can invite his friends to a match and then an invitation banner will appear on the friends' devices. They can tap on the banner and accept the invitation. Now, this works fine if the friend has run the app before and has installed the below invitation handler (installed in the 2nd view controller of the app)

- (void) installInvitationHandler
{
    [GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) {
        // Insert game-specific code here to clean up any game in progress.
        if (acceptedInvite)
        {
            if(self.myConnectingVC) return;
            else if(self.myMatchmakerVC)
            {
                [self dismissViewControllerAnimated:YES completion:^{
                    self.myMatchmakerVC = nil;
                    GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc] initWithInvite:acceptedInvite];
                    mmvc.matchmakerDelegate = self;
                    self.myConnectingVC = mmvc;
                    [self presentViewController:mmvc animated:YES completion:nil];
                }];
            }
            else
            {
                GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc] initWithInvite:acceptedInvite];
                mmvc.matchmakerDelegate = self;
                [self presentViewController:mmvc animated:YES completion:nil];
            }
        }
        else if (playersToInvite)
        {
            [self createMatchWithPlayersToInvite:playersToInvite];
        }
    };
}

The problem is, what do I do if the friend has never run the app before or if the friend has not progressed far enough in the app to reach the installInvitationHandler method? If this happens, if the friend taps on the invitation banner, the app will open but it will not accept the invitation.

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Nosrettap
  • 10,940
  • 23
  • 85
  • 140
  • When the app is launched via the game center notification, can't you just run the installInvitationHandler method then? – Chris Truman Jan 22 '13 at 23:40
  • I'm not sure where to obtain the GKInvite from then? – Nosrettap Jan 23 '13 at 00:10
  • Won't it be passed in your AppDelegate's launchWithOptions method? Apple Docs say "To receive invitations from other players, your game must provide an invitation handler." Can you even get push notification invites before you setup the inviteHandler? – Chris Truman Jan 23 '13 at 00:22
  • I've done some testing and the dictionary in the launch options method is null. Also, yes, you can get invitations before you setup the invite handler – Nosrettap Jan 23 '13 at 01:07
  • After scouring the GameKit docs, it seems like Apple provides no way to respond to an invite that happens after your install the app, but have not reached the point where you register the inviteHandler. I think you just ignore that invite and the user will have to invite the player again. – Chris Truman Jan 23 '13 at 01:57
  • possible duplicate of [Game Center Invitation handler, Where does it belong?](http://stackoverflow.com/questions/6285124/game-center-invitation-handler-where-does-it-belong) – Drux Mar 25 '14 at 11:31

2 Answers2

1

You should add the inviteHandler immediately after your app launches. The GKInvite object is passed in when the handler is called.

[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) {
    //By the time this block is called, you have already received the
    //invite, it's passed as a parameter
    if (acceptedInvite) {
        //This is your invite
    } else if (playersToInvite) {
        //The player has launched your app from the Game Center app, invite these players.
    }
};
dalton_c
  • 6,876
  • 1
  • 33
  • 42
0

I found it best to attach the inviteHandler as a completion block to the authenticateHandler of GKLocalPlayer.

This is for iOS 6.0 onwards...

[GKLocalPlayer localPlayer].authenticateHandler = ^(UIViewController *viewController,     NSError *error)
    {
        if([GKLocalPlayer localPlayer].authenticated)
            _gameCenterFeaturesEnabled = YES;

        // Present the view controller if needed
        if (![GKLocalPlayer localPlayer].authenticated)
        {
            if(viewController)
                [self presentViewController:viewController];
            return;
        }

        if (error)
        {
            if(completionHandler)
                completionHandler(error);
        }
        else
        {
            [self authenticationCompleted];
            if(completionHandler)
                completionHandler(nil);
        }
    };

With the completion handler being...

if(!error)
    {           
        CCLOG(@"Adding invite handler.");
        [GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) {
            CCLOG(@"Invite recieved.");
            // Insert game-specific code here to clean up any game in progress.
            if (acceptedInvite)
            {
                GKMatchmakerViewController *mmvc = [[GameDataCache sharedData].match createWithInvite:acceptedInvite];
                mmvc.matchmakerDelegate = [GameDataCache sharedData].match;
            }
            else if (playersToInvite)
            {
                GKMatchRequest *request = [[GKMatchRequest alloc] init];
                request.minPlayers = 2;
                request.maxPlayers = 2;
                request.playersToInvite = playersToInvite;

                GKMatchmakerViewController *mmvc = [[GameDataCache sharedData].match createNewRequest:request cancelledBlock:nil];
                mmvc.matchmakerDelegate = [GameDataCache sharedData].match;
            }
        };
    }

Pre iOS6 needs to call authenticateWithCompletionHandler on the localPlayer instead of assigning the authenticateHandler property.

aronspring
  • 276
  • 2
  • 11
  • Note: inviteHandler is now deprecated (since iOS 7). See this SO question http://stackoverflow.com/questions/20567104/gkmatchmaker-invite-handler-deprecated – thomers Sep 29 '15 at 09:24