ios game center authentication keeps failing - ios

Basically under ViewController's viewdidload method, I put:
[self authenticateLocalUser];
And authenticateLocalUser method is:
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
if (localPlayer.isAuthenticated == NO)
{
NSLog(#"FAILED");
}
Why doesn't it authenticate? Shouldn't the class method for GKLocalPlayer authenticate automatically? Also, if it does authenticate, should I get the "welcome back __" on the top? I am not getting this banner at all. Is there something I need to do beforehand?

In iOS6 and above you need to present Game Center login view with setAuthenticateHandler api.
Here is Code:
#define CHECK_IOS_LESS_THAN(version) ([[[UIDevice currentDevice] systemVersion] \
compare:version options:NSNumericSearch] == NSOrderedAscending)
- (void) authenticateLocalUser
{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
if (CHECK_IOS_LESS_THAN(#"6.0"))
{
// ios 5.x and below
[localPlayer authenticateWithCompletionHandler:^(NSError *error)
{
[self checkLocalPlayer];
}];
}
else
{
// ios 6.0 and above
[localPlayer setAuthenticateHandler:(^(UIViewController* viewcontroller, NSError *error)
{
if (!error && viewcontroller)
{
[self.navController
presentViewController:viewcontroller animated:YES completion:nil];
}
else
{
[self checkLocalPlayer];
}
})];
}
}
- (void)checkLocalPlayer
{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
if (localPlayer.isAuthenticated)
{
/* Perform additional tasks for the authenticated player here */
[self processGameCenterLoginSuccess];
}
else
{
/* Perform additional tasks for the non-authenticated player here */
[self processGameCenterLoginFaild];
}
}
After adding this code, goto device settings and Reset:
Device: Settings->General->Reset->Reset All Settings
Simulator: Settings->General->Reset->Reset Locations and Privacy

You need to install an authenticateHandler. A section in Apple's Game Center Programming Guide gives a verbatim example. The code starts like this (see that section as linked for full source code):
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = // ...

Related

iOS Login again into GameCenter

How can I display the GameCenter Login view again, if a user has canceled during first login attempt.
I am using the following code from raywenderlich tutorial,
-(void) authenticateLocalPlayer {
__weak GKLocalPlayer* localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error) {
[self setLastError:error];
if (localPlayer.authenticated) {
_gameCenterFeaturesEnabled = YES;
currentPlayer = localPlayer;
//NSLog(#"Authenticated User");
[self.delegate2 enableButtonOnAuthentication];
} else if(viewController) {
[self presentViewController:viewController];
} else {
_gameCenterFeaturesEnabled = NO;
}
};
}
The above method is called from viewDidLoad,
[[GameKitHelper sharedGameKitHelper] authenticateLocalPlayer];
[[GameKitHelper sharedGameKitHelper] setDelegate2:self];
If a user cancels the login, I am displaying a message, "to play you must login".
And if tries to call the above method again on a button click the block code does not seems to execute.
Can you point out to what am I doing wrong here?

GameCenter login screen- cancel button pressed event

I present the GameCenter login screen:
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error) {
if (viewController != nil) {
[self presentViewController:gameCenterLoginController animated:YES completion:nil];
}
And I want to do something after the login screen dismiss.
The login screen can be dismissed in 2 ways:
User logged in successfully
User dismissed the login screen
How can I catch the dismiss login screen event (second way)?
(And no, the UIViewController lifecycle methods doesn't fire- like viewDidAppear:)
Here is how I did in my projects:
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error) {
if (viewController != nil) {
[self presentViewController:gameCenterLoginController animated:YES completion:nil];
}
else if (localPlayer.isAuthenticated)
{
// user is authenticated - do what next steps
}
else
{
NSLog(#“Local player is not authenticated or was canceled”);
//do thing …
}

IOS Game Center GKLocalPlayerListener

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");
}
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.
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_];
}
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.

Game Center authentication always results in sigabrt

This is driving me crazy. Every time I try to authenticate the local player with Game Center I get a thread-1 sigkill. It happens asynchronously after I set the localPlayer's authenticateHandler like so:
- (void)authenticateLocalPlayer
{
if([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0)
{
GKLocalPlayer __weak *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error)
{
if (viewController != nil)
{
[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:viewController animated:YES completion:nil];
}
else if (localPlayer.isAuthenticated)
{
NSLog(#"Player authenticated");
}
else
{
NSLog(#"Player authentication failed");
}
};
}
}
Any ideas?
I've often seen the systemVersion tested with a string comparison instead of a number comparison. Try just printing the value of
[[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0
to verify there's nothing wrong with that expression. I know the following method works:
-(BOOL) os6 {
NSString *targetSystemVersion = #"6.0";
NSString *currentSystemVersion = [[UIDevice currentDevice] systemVersion];
if ([currentSystemVersion compare:targetSystemVersion options:NSNumericSearch] == NSOrderedAscending) {
return NO; //current system version is less than 6.0
} else {
return YES;
}
}
[GKLocalPlayer localPlayer] returns a singleton and __weak releases it at some time (I don't understand when that happens, but at some future time). localPlayer might be getting released, along with the block, before the block finishes executing. There's no need to release a singleton. Try removing __weak.
Try putting __weak before GKLocalPlayer.
It's the only difference I can see between your code and the code I use...

GKGameCenterViewController analog in ios 5?

iOS 6 provides new view controller to display Game Center info: GKGameCenterViewController.
Does iOS 5.1 provide something similar (except separate controllers for Leader-board and Achievements)?
Here's how I handle both the old and new GameCenter APIs in my app which supports everything between iOS 4 and 7.
I started with the GameCenterManager.m sample code.
1) In GameCenterManager.m, I changed authenticateLocalUser
- (void) authenticateLocalUser
{
if([GKLocalPlayer localPlayer].authenticated == NO)
{
if ([[GKLocalPlayer localPlayer] respondsToSelector: #selector(setAuthenticateHandler:)]) {
[[GKLocalPlayer localPlayer] setAuthenticateHandler:(^(UIViewController* viewcontroller, NSError *error) {
[self callDelegateOnMainThread: #selector(processGameCenterAuth:error:) withArg: viewcontroller error: error];
})];
} else {
[[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error)
{
[self callDelegateOnMainThread: #selector(processOldGameCenterAuth:) error: error];
}];
}
}
}
2) And then in my main view controller, here are my two versions of the authentication handler.
- (void) processOldGameCenterAuth: (NSError*) error; {
// for iOS < 6.0 without the viewcontroller parameter
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
if (localPlayer.isAuthenticated) {
usingGamecenter = TRUE;
[self.gameCenterManager reloadHighScoresForCategory: kOverallLeaderboard];
} else {
usingGamecenter = FALSE;
}
// *** this is where you update your UI after game center login
}
- (void) processGameCenterAuth: (UIViewController*) gameCenterController error: (NSError*) error; {
if (gameCenterController) {
[self presentViewController:gameCenterController animated:YES completion:nil];
} else {
[self processOldGameCenterAuth: error];
}
}

Resources