10

I was trying to implement an event listener in a turn based game so a player can receive when his turn is active or when he is invited by a friend. GKTurnBasedEventHandler is deprecated in IOS 7 and i read in the documentation that i should use GKLocalPlayerListener; but that's the extend of it. Is there someone who used it already, because there is no info anywhere.

This is what i tried before, and it does not work.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
    [localPlayer authenticateWithCompletionHandler:^(NSError *error)
     {
         if (localPlayer.isAuthenticated)
         { 
             GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
             [localPlayer registerListener:self];
         }
     }];

    return YES;
}

-(void)handleInviteFromGameCenter:(NSArray *)playersToInvite
{
    NSLog(@"test");
}

- (void)player:(GKPlayer *)player receivedTurnEventForMatch:(GKTurnBasedMatch *)match didBecomeActive:(BOOL)didBecomeActive
{
    NSLog(@"test");
}
Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Macaret
  • 797
  • 9
  • 33
  • have you figured out or found anything else on this? i am having trouble finding anything on using the GKLocalPlayerListener. the documentation and examples available still leverage deprecated APIs. – iksnae Oct 26 '13 at 02:09
  • Not yet, some other urgent stuff came up, but if i do i will post the solution. – Macaret Oct 27 '13 at 05:19
  • It works for me to some degree. The methods are analogous to the now deprecated ones, except that the current player is passed as well. However what I'm having problems with is figuring out when to de/reregister listeners e.g. when the app switches between bg/fg. This was also an issue for invite listeners in iOS 6. – Drux Oct 30 '13 at 08:01
  • 1
    I'm getting the same sort of flakey behavior. Sometimes the listener gets the turn or saved turn event. Most of the time, nothing. I have to restart the game to get the match info sync'd up. Also, the information in Game Center is not displayed as current. Whose turn it is isn't right until I reload the game. I'm using the sandboxed game center. – AutomatonTec Nov 05 '13 at 07:31

3 Answers3

2

Here is some code that I use in order to register GKLocalPlayerListener

__weak GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error) {
   if (viewController) {
         [authenticateFromViewController presentViewController:viewController animated:YES completion:^{
          [localPlayer registerListener:self];
          NSLog(@"Authenticated. Registering Turn Based Events listener");
        }];
  } else if (localPlayer.authenticated) {
         [localPlayer registerListener:self];
         NSLog(@"User Already Authenticated. Registering Turn Based Events listener");
  } else {
         NSLog(@"Unable to Authenticate with Game Center: %@", [error localizedDescription]);
  }
};

The documentation states that you should only register for an GKLocalPlayerEventListener once so you could improve this code by checking if you've already registered.

Note that authenticateWithCompletionHandler is deprecated in iOS 6 and they recommend setting the authenticateHandler property like I did above.

aahrens
  • 5,522
  • 7
  • 39
  • 63
1

I believe you were there. Just this time do a couple of things. Make sure you dont add multiple listeners also before you add a listener, just incase unregister all listeners.

I made sure I only did this once in my whole project, but I get the local player multiple times.

-(void) onLocalPlayerAuthChanged:(GKLocalPlayer*)authPlayer {

    [authPlayer unregisterAllListeners];
    [authPlayer registerListener:_Whatever_];

}
Eugene Loy
  • 12,224
  • 8
  • 53
  • 79
tomJ
  • 11
  • 1
1

I might be a little late, but hopefully it will help someone out there...

This is what I do. According to Apple's documentation I create [my] own method that displays an authentication view when appropriate for [my] app.

    - (void)authenticateLocalUser
    {
        if ([GKLocalPlayer localPlayer].authenticated == NO) {
            __weak typeof(self) weakSelf = self;
            __weak GKLocalPlayer *weakPlayer = [GKLocalPlayer localPlayer];

            weakPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error) {
                if (viewController != nil) {
                    [weakSelf showAuthenticationDialogWhenReasonable:viewController];
                } else if (weakPlayer.isAuthenticated) {
                    // Player has been authenticated!
                    [weakPlayer registerListener:weakSelf];
                } else {
                    // Should disable Game Center?
                }
            };

        } else {
            // Already authenticated
            [[GKLocalPlayer localPlayer] registerListener:self];
        }
    }


    -(void)showAuthenticationDialogWhenReasonable:(UIViewController *)controller
    {
        [[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:controller animated:YES completion:nil];
    }

This code is inside a singleton helper class, it might be simplified if you have it on your own class.

Eric
  • 3,301
  • 4
  • 33
  • 39
  • Thank you very very much, it was pending from the last 15 hours for me, and simply delegating was mentioned everywhere, but the correct syntax wasn't available. And I really converted this to swift for my own purpose. https://stackoverflow.com/questions/44889019/gkturnbasedeventlistener-could-not-be-set-to-delegate-of-my-viewcontroller – Asim Khan Jul 04 '17 at 06:01