iOS GameCenter Integration Error - ios

In DidFinishLaunchingWithOptions I am trying to authenticate the player with this code
// Authenticate Player with Game Center
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
// Handle the call back from Game Center Authentication
[localPlayer localPlayer.authenticateHandler:^(NSError *error)
{
if (localPlayer.isAuthenticated)
{
// Player was successfully authenticated.
// Perform additional tasks for the authenticated player.
}
else if (error != nil)
{
NSLog(#"error : %#", [error description]);
}
}];
return YES;
}
But I get the error on this line [localPlayer localPlayer.authenticateHandler:^(NSError *error) saying missing a square bracket ']' and is pointing at the full stop '.'
I can't get this working
Thanks

You're not sending a message to the local player instance, so this is plain grammatically incorrect.
Please read.
You should be doing something like:
[localPlayer setAuthenticateHandler:
^(UIViewController *viewController, NSError *error) {
// ...
}
];

Related

game center login form when player not authenticated sprite kit

I created a class of NSObject and I have this authenticate function in it:
-(void)authenticateLocalUser {
if(!gameCenterAvailable) { return; }
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
__weak GKLocalPlayer *blockLocalPlayer = localPlayer;
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error){
NSLog(#"authenticateHandler");
if (viewController != nil)
{
NSLog(#"viewController != nil");
}
else if (blockLocalPlayer.isAuthenticated)
{
NSLog(#"localPlayer already authenticated");
//do some stuff
}
else
{
NSLog(#"local player not authenticated");
// not logged in
}
};
}
Its the new version i looked up , but its not displaying the Game Center login form.
Im calling this method in my AppDelegate.m if you need this information.
I think I have to put something in there when the player is not logged in like get the login form. But I don't know how.
Thanks for any help!
There are two things you need. First, you need to check error. If it is set, the viewController will usually be nil and your code will incorrectly assume that you're logged in and communicating happily Game Center. You may appear logged in based on cached credentials, but in most cases, you won't actually be seeing current data from the server, you'll just have access to whatever data was last cached on the device.
Second, you have to present the viewController to the user if they're not logged in. Try this:
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error)
{
NSLog(#"authenticateHandler");
if (error)
{
//Examine the error. IOS may show you as "authenticated" based on
//cached credentials, but you probably can't really communicate with
//game center in any meaningful manner
}
else if (viewController != nil)
{
//You're not logged in, show the login viewController
NSLog(#"viewController != nil");
UIViewController *mainVC = [[[[UIApplication sharedApplication]delegate] window] rootViewController];
[mainVC presentViewController:viewController animated:NO completion:^
{
//the login view controller has been dismissed. Did it work?
if ([GKLocalPlayer localPlayer].authenticated)
{
//Yes, Login worked. enable whatever comes next after successful login
}
else
{
//No, login failed or was canceled.
}
}];
}
else if (blockLocalPlayer.isAuthenticated)
{
NSLog(#"localPlayer already authenticated");
//do some stuff
}
else
{
NSLog(#"local player not authenticated");
// not logged in
}
};

IOS Game Center: How to know when default sign in form for game center is finished?

I was wondering how to know when Game Center sign in form is finished by the user. I am doing Facebook sign in automatically but I need to wait for Game Center login to finish. Is there any way of knowing that?
-(void) authenticateLocalPlayer {
GKLocalPlayer* localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler =
^(UIViewController *viewController,
NSError *error) {
[self setLastError:error];
if (localPlayer.authenticated) {
_gameCenterFeaturesEnabled = YES;
NSLog(#"local Player Info: %#",localPlayer);
[[UserManager sharedInstance] setGameCenterId:localPlayer.playerID];
[[UserManager sharedInstance] setUserName:localPlayer.alias];
[self retrieveFriends];
} else if(viewController) {
[self presentViewController:viewController];
} else {
_gameCenterFeaturesEnabled = NO;
}
};
}
-(void) setLastError:(NSError*)error {
_lastError = [error copy];
if (_lastError) {
NSLog(#"GameKitHelper ERROR: %#", [[_lastError userInfo]
description]);
}
}
-(UIViewController*) getRootViewController {
return [UIApplication
sharedApplication].keyWindow.rootViewController;
}
-(void)presentViewController:(UIViewController*)vc {
UIViewController* rootVC = [self getRootViewController];
[rootVC presentViewController:vc animated:YES completion:nil];
}
Here is a quote from authenticateHandler documentation
The authenticate handler will be called whenever the authentication
process finishes or needs to show UI. The handler may be called
multiple times. Authentication will happen automatically when the
handler is first set and whenever the app returns to the foreground.
If the authentication process needs to display UI the viewController
property will be non-nil. Your application should present this view
controller and continue to wait for another call of the
authenticateHandler. The view controller will be dismissed
automatically.
Possible reasons for error:
1. Communications problem
2. User credentials invalid
3. User cancelled
So the block will be called multiple times,
For example if user is not logged in, a view-controller will be passed to this block, after you present it and user submits the form, he block will be executed once again.
Here is code that handles authentication:
- (void)authenticateLocalPlayer
{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
__weak typeof(localPlayer) weakLocalPlayer = localPlayer;
localPlayer.authenticateHandler =
^(UIViewController *viewController, NSError *error)
{
if (error) {
// Something happened, handle it...
return;
}
__strong typeof(weakLocalPlayer) strongLocalPlayer = weakLocalPlayer;
if (viewController) {
// Just show it, user needs to submit the form
return;
}
if (strongLocalPlayer.isAuthenticated) {
// User completed login, do FB login
} else {
// GameKit is disabled, show guide to enable it
}
};
}

Game Center Authenticate Local Player

I am trying to authenticate the local player using the following code:
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
if(!localPlayer.authenticated) {
localPlayer.authenticateHandler = ^(UIViewController* controller, NSError *error) {
if(controller != nil)
[self presentModalViewController:controller animated:YES];
};
}
But the problem is that even though [GKLocalPlayer localPlayer].authenticated is false, the controller that is returned in the authenticationHandler block is always nil. Therefore gamer center always seems to be disabled.
The problem was caused by the authenticateHandler being set twice. The handler should be set once for the duration of the application's life cycle. Subsequent authenticateHandler property being set after the first time will yield unexpected results like the problem I described in the question.
I found this authentication code works fine in iOS 8.
- (void)authenticateLocalPlayer
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
if (localPlayer.isAuthenticated) {
[[NSNotificationCenter defaultCenter] postNotificationName:LocalPlayerIsAuthenticated object:nil];
return;
}
localPlayer.authenticateHandler =
^(UIViewController *viewController, NSError *error) {
[self setLastError:error];
if(viewController != nil){
[self setAuthenticationViewController:viewController];
} else if([GKLocalPlayer localPlayer].isAuthenticated) {
NSLog(#"connected to gk");
_GKConnected = YES;
[[NSNotificationCenter defaultCenter] postNotificationName:LocalPlayerIsAuthenticated object:nil];
}
else {
_GKConnected = NO;
}
};
// REGISTER LISTENER FOR INVITES
[localPlayer registerListener:self];
}
The notification strings can be any constant string (it is good practice to prefix a reverse DNS for use with NotificationCenter org.myapp.notificationname).
In the original OP question was an error in retrieving the getter for the authenticated property in GKPlayer instance: the property name is authenticated but the getter has to be isAuthenticated.
Can be trivial to catch out those semantic typos, whilst the compiler doesn't warn you because it could be more code behind a simple property accessed with dot notation and by default setters begins with is.
By the way I can add a link to a well known tutorial with working sample tutorial:
http://www.raywenderlich.com/60998/game-center-tutorial-how-to-make-a-simple-multiplayer-game-with-sprite-kit-part-2

iOS: Retrieve Game Center friends who are online

I can retrieve all Game Center friends with this code...
GKLocalPlayer *lp = [GKLocalPlayer localPlayer];
if (lp.authenticated)
{
[lp loadFriendsWithCompletionHandler:^(NSArray *friends, NSError *error)
{
NSLog(#"MY FRIENDS: %#",friends);
if (friends != nil)
{
[GKPlayer loadPlayersForIdentifiers:friends withCompletionHandler:^(NSArray *players, NSError *error)
{
if (error != nil)
{
// Handle the error.
NSLog(#"PLAYERLIST ERROR: %#",[error localizedDescription]);
}
if (players != nil)
{
// Process the array of GKPlayer objects.
NSLog(#"PLAYERS: %#",players);
}
}];
}
}];
}
... however, is there a way to retrieve only the friends with GameKit who are online?
It does not look like you are able to. Since GKPlayer does not offer any way to view if a player is online or not.
Also since technically once a person logs on to Game Center they are "Online" till they log off. Meaning they could be online for days while using their phone. When they are logged on if you send them an invite they will get the trumpet noise.
http://developer.apple.com/library/IOS/#documentation/GameKit/Reference/GKPlayer_Ref/Reference/Reference.html#//apple_ref/doc/uid/TP40009599

GKSConnSettings message in xcode console

Got this message suddenly in my app -
<Info>: 22:20:44.800330 com.apple.AVConference: GKSConnSettings: set server: {
"gk-cdx" = "17.173.254.218:4398";
"gk-commnat-cohort" = "17.173.254.220:16386";
"gk-commnat-main0" = "17.173.254.219:16384";
"gk-commnat-main1" = "17.173.254.219:16385";
}
Where does it comes from?
In iOS 6.0 + this log will show up as soon as your localPlayer is authenticated, i.e. set
[GKLocalPlayer localPlayer].authenticateHandler = ^(UIViewController *viewController, NSError *error) {
if (viewController != NULL) {
// present the viewController now
} else if ([GKLocalPlayer localPlayer].isAuthenticated) {
NSLog(#"Already authenticated");
} else {
NSLog(#"Not authenticated, disable GameCenter");
}
};
and if necessary present the viewController to log into GameCenter
My first instinct tells me it could be related to your environment. Are you working from a virtual machine by chance? This happened to be my case.

Resources