GKMatchmaker findMatchForRequest invite never received
Asked Answered
S

3

5

I'm trying to invite nearby players to a match, but the invite is either never sent or never received.

GKMatchMaker startBrowsingForNearbyPlayersWithHandler works and returns nearby players that are on same wifi, but then I use findMatchForRequest and it returns a match without any players, and the players I try to invite never receive an invite notification. Here is my code.

I start by authenticating the local player:

GKLocalPlayer.localPlayer.authenticateHandler= ^(UIViewController *controller, NSError *error)
{
    if (error)
    {
        NSLog(@"%s:: Error authenticating: %@", __PRETTY_FUNCTION__, error.localizedDescription);
        return;
    }
    if(controller)
    {
        // User has not yet authenticated
        [pViewController presentViewController:controller animated:YES completion:^(void)
         {
             [self lookForNearbyPlayers];
         }];
        return;
    }
    [self lookForNearbyPlayers];
};

-(void)lookForNearbyPlayers
{
    if(!GKLocalPlayer.localPlayer.authenticated)
    {
        NSLog(@"%s:: User not authenticated", __PRETTY_FUNCTION__);
        return;
    }

I register my view controller as a delegate of GKLocalPlayerListener:

    [GKLocalPlayer.localPlayer registerListener:self]; // self is a view controller.

    // This works. My test local player which is a second device and appleID I setup shows up when this handler is called.
    [GKMatchmaker.sharedMatchmaker startBrowsingForNearbyPlayersWithHandler:^(GKPlayer *player, BOOL reachable)
    {
         NSArray * paPlayers= [NSArray arrayWithObject:player];
         _pMatchRequest= [[GKMatchRequest alloc] init];
         _pMatchRequest.minPlayers= 2;
         _pMatchRequest.maxPlayers= 4;
         _pMatchRequest.recipients = paPlayers;
         _pMatchRequest.inviteMessage = @"Join our match!";
         _pMatchRequest.recipientResponseHandler = ^(GKPlayer *player, GKInviteeResponse response)
         {
             // This is never called.
             NSLog((response == GKInviteeResponseAccepted) ? @"Player %@ Accepted" : @"Player %@ Declined", player.alias);
         };

         // This returns with a match without any players.
         [GKMatchmaker.sharedMatchmaker findMatchForRequest:_pMatchRequest withCompletionHandler:^(GKMatch *match, NSError *error)
          {
              if(error)
              {
                  NSLog(@"%s:: %@", __PRETTY_FUNCTION__, error.localizedDescription);
                  return;
              }
              else if(match != nil)
              {
                  _pMatch= match;
                  match.delegate = self;
                  NSLog(@"players count= %lu", (unsigned long)_pMatch.players.count); // Always returns 0
              }
          }];
     }
}

I have delegate methods for GKLocalPlayerListener setup, but they are never called:

- (void)player:(GKPlayer *)player didRequestMatchWithRecipients:(NSArray<GKPlayer *> *)recipientPlayers
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

- (void)player:(GKPlayer *)player didAcceptInvite:(GKInvite *)invite
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
}

Does anyone know how to get this to work without GKMatchmakerViewController and for iOS9? The only examples I can find have the deprecated -inviteHandler method.

Supercharger answered 19/4, 2016 at 20:13 Comment(4)
You have verified that your development environment has all the entitlements set up? And the other devices are compiled with the same certificates etc?Lozenge
@Larusso, Yes I have, and I just did again to make sure. Any thoughts? Thanks for your input!Supercharger
No I`m sorry. I checked some code I used last time I played around with game center. It is in swift and used the old api. I had more struggle to get it to work because of the certificate stuff rather than coding itself.Lozenge
May be you are just trying to find a match in one device only. Basically this function "findMatchRequest" should be called simultaneously in two different devices/simulators and then you would receive a successful response.Wham
S
0

This code is working in Swift if you know how you can convert it to Objective-C and to try it.

GKMatchmaker.sharedMatchmaker().findMatchForRequest(
    request,
    withCompletionHandler: {(match : GKMatch!, error: NSError!) -> Void in
        NSLog("This works")
})
Synecology answered 28/4, 2016 at 21:31 Comment(1)
Thank you for the answer. I'll give this a try here soon. Maybe Apple is pushing us towards Swift these days.Supercharger
T
0

Based on multiple questions here on SO, Game Center seems to be getting stuck from time to time. In the best case, it returns "Game not recognized" errors. In the worst case, it just cheerfully returns nil to GC calls. Sometimes it resumes working on it's own, sometimes it doesn't. But it seems you can kickstart it again by logging into iTunesConnect and do any of the following:

  1. Add a leaderboard
  2. Change the default leaderboard
  3. Add an achievement

I've added this to my debugging routine. If some aspect of GC stops working, or returns nil, I try making one of the above changes in iTunesConnect before proceeding. In my case, I get the "game not recognized" several times per week, but several others have noted the "nil return values."

Tremolite answered 22/5, 2016 at 19:42 Comment(0)
O
0

I know this an older post, but I ran across it when trying to establish a connection between several app instances over the internet. I believe the part you're missing is that after registering for the listener, you need to receive the connected status with

    - (void)match:(GKMatch *)match
        player:(GKPlayer *)player
        didChangeConnectionState:(GKPlayerConnectionState)state
 {
     NSLog(@">>> did change state");

     if (state == GKPlayerStateConnected)
     {
         NSLog(@">>>> match:%@ did change to Connected for player %@ ",match, player.displayName);

     }
   else if (state == GKPlayerStateDisconnected)
   {
    NSLog(@">>>> match:%@ disconnected for player %@ ",match, player.displayName);
   }

I find the match has 0 players when the completionHandler is called from findMatchForRequest:, but that I can successfully use the GKMatch and GKPlayer as returned in didChangeConnectionState: Hope that helps someone who reads this long after the OP.

Openhearted answered 27/4, 2020 at 12:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.