GameCenter Report Score - Local declaration hides instance variable - ios

I'm adding Game Center functionality to my app, and I have run into something strange that I can't get my head around...
I've used this exact method (and code) in 5 games, so I can't see why it's throwing a warning message now...
I get 2x "local declaration of 'score' hides instance variable" in the ReportScore method...
The code is as follows:
-(void)reportScore{
GKScore *score = [[GKScore alloc] initWithLeaderboardIdentifier:_leaderboardIdentifier];
score.value = gameScore; //gameScore is games Score that needs submitting
[GKScore reportScores:#[score] withCompletionHandler:^(NSError *error) {
if (error != nil) {
NSLog(#"%#", [error localizedDescription]);
}
}];
}
I've tried declaring the variable like this in the .h:
#property (nonatomic) GKScore *score;
But that introduces an autosynthesised warning instead... I don't understand why this is happening when it doesn't do this in any other apps of mine?

I can't believe I did this... It shows how easy it is to miss things when you're staring at code so long...
It turns out, I have a UIImageView with the name score...
.h
IBOutlet UIImageView *score;
Simply changing the GKScore variable name, the warnings disappeared...
-(void)reportScore{
GKScore *this_score = [[GKScore alloc] initWithLeaderboardIdentifier:_leaderboardIdentifier];
this_score.value = gameScore;
[GKScore reportScores:#[this_score] withCompletionHandler:^(NSError *error) {
if (error != nil) {
NSLog(#"%#", [error localizedDescription]);
}
}];
NSLog(#"Reported to Game Center...");
}
What a doughnut!

Related

Reporting score from a different UIViewController IOS

I'm not sure what is going on.
If i report an int score from the same viewcontroller, it seems to work fine. I can send that number to the leaderboard set up in game center.
When I report an int score that is from another viewcontroller, it doesn't work. At first I thought it was because the numbers weren't in int64_t. I'm not sure if that is really the issue though.
I'm fairly new to ios programming. If this is a duplicate question, please direct me in the right direction. I really appreciate any help.
-(IBAction)report:(id)sender{
[self reportScore]; //just calling the method
}
-(void)reportScore{
GKScore *score = [[GKScore alloc] initWithLeaderboardIdentifier:_leaderboardIdentifier];
score.value = HighScore; //HighScore is the int I want from another viewcontroller.
[GKScore reportScores:#[score] withCompletionHandler:^(NSError *error) {
if (error != nil) {
NSLog(#"%#", [error localizedDescription]);
}
}];
}
I guess
GKScore *score = [[GKScore alloc] initWithLeaderboardIdentifier:_leaderboardIdentifier];
This line creating the object each time. And thats the reason you are getting the wrong result.
Try to create GKScore *score object only once which will be global and then access it.

End a turn in Game Center turn based match.

I´m having troubles with ending turns in my turn based game app.
The method I´m using is
GKTurnBasedMatch *currentMatch = [[GCTurnBasedMatchHelper sharedInstance] currentMatch];
[currentMatch endTurnWithNextParticipants:p turnTimeout:1000 matchData:data completionHandler:^(NSError *error) {
if (error) {
NSLog(#"%#", error);
}
}];
Here p is my NSArray for nextParticipants and this is my declaration for it:
and this is the declaration and assignment for
NSArray *p = [[currentMatch.participants reverseObjectEnumerator] allObjects];
I´m reversing the participants array to get the turn order of the players. (Only 2)
This all compile and runs without an error, but the turn never actually passes to the other player!
Thinking my p-array is the problem I´ve tried passing it without reversing it which produced the same result.
Does anyone know the correct way to handle this?
Replace your code with
GKTurnBasedMatch *currentMatch = [[GCTurnBasedMatchHelper sharedInstance] currentMatch];
GKTurnBasedParticipant *nextPerson = [currentMatch.participants objectAtIndex:((currentIndex + 1) % [currentMatch.participants count])];
[currentMatch endTurnWithNextParticipants:[NSArray arrayWithObject:nextPerson] turnTimeout:1000 matchData:matchData completionHandler:^(NSError *error) {
if (error) {
NSLog(#"%#", error);
}
}];

iOS 7 - game center leaderboard integration

- (void) reportScore: (int64_t) score forLeaderboardID: (NSString*) identifier
{
GKScore *scoreReporter = [[GKScore alloc] initWithLeaderboardIdentifier: identifier];
scoreReporter.value = score;
scoreReporter.context = 0;
NSArray *scores = #[scoreReporter];
[GKLeaderboard reportScores:scores withCompletionHandler:^(NSError *error) {
//Do something interesting here.
}];
}
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/GameKit_Guide/LeaderBoards/LeaderBoards.html
On the above site, I used the above code (and the title was Reporting a score to Game Center (iOS 7)) but on the GKLeaderboard reportScores... line, I get an error saying that there is no such method. How do i fix this without using GKScore's deprecated reportScoreWithCompletionHandlerMethod?
So apple's thing had a typo. GKLeaderboard was supposed to be GKScore in the reportScores line.

GKScore doesn't get incremented

Why score doesn't get incremented?
GKLeaderboard *lb = [[GKLeaderboard alloc] initWithPlayerIDs:#["G:1518137155"]];
lb.category = #"top_matcher";
[lb loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
if(error == nil){
GKScore *score = [scores lastObject];
if(score) {
score.value += 40;
[score reportScoreWithCompletionHandler:^(NSError *error) {
NSLog(#"ERR: %# SC:%lld %# %# %d", error, score.value, score.playerID, score.category, scores.count);
}];
}
}
}];
I see no error in output
ERR: (null) SC:61 G:1689523782 top_matcher 1
It's clearly documented here.
Almost all classes in Game Kit that send data to or retrieve information from Game Center expect the device to have an authenticated local player. The work those classes do is always on behalf of the local player. For example, if your game reports scores to a leaderboard, it can only report a score earned by the local player.

iOS GameCenter GKErrorCanceled

I'm in sandbox mode implementing game center in my application. The problem comes when I log to gameCenter, in some devices works fine in some others I get a GKErrorCanceled without even get the interface shown.
This devices don't have any user logged in gameCenter so it's not related to have a non sandbox account logged. My code is:
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
//First we try the new iOS6 authentification method for gamekit, if it's not implemented we will use the deprecated one
if ([localPlayer respondsToSelector:#selector(setAuthenticateHandler:)]) {
if (localPlayer.isAuthenticated) {
this->setState(connectionLoged);
this->getDelegate().socialConnectionDidSucceedLogin(*this);
return;
}
else if(!localPlayer.isAuthenticated && localPlayer.authenticateHandler){
this->setState(connectionClosed);
this->getDelegate().socialConnectionDidFailToLogin(*this, std::string("The user already resign to login"));
return;
}
else{
localPlayer.authenticateHandler = ^(UIViewController* viewController, NSError* error){
if (localPlayer.isAuthenticated)
{
_name = [localPlayer.displayName UTF8String];
_userId = [localPlayer.playerID UTF8String];
[GKPlayer loadPlayersForIdentifiers:localPlayer.friends withCompletionHandler:^(NSArray *players, NSError *error) {
for (GKPlayer* player in players) {
if ([player isFriend]) {
NSDictionary* dict =
#{#"displayName" : player.displayName,
#"alias" : player.alias,
#"playerID" : player.playerID};
AttrDictionary* playerInfo = [dict hydraAttrDictionary];
SocialFriend* socialfriend = this->getNewFriendInstance(*playerInfo);
this->addFriend(socialfriend);
delete playerInfo;
}
}
this->getDelegate().socialConnectionDidSucceedLogin(*this);
this->setState(connectionLoged);
}];
}
else if(viewController){
UIViewController* rootViewController = (UIViewController*) [UIApplication sharedApplication].keyWindow.rootViewController ;
[rootViewController presentModalViewController:viewController animated:YES];
}
else{
if(error){
this->getDelegate().socialConnectionDidFailToLogin(*this, std::string([error.description UTF8String]));
}
else{
this->getDelegate().socialConnectionDidFailToLogin(*this, std::string("User cancelled login"));
}
}
};
}
}
//deprecated at IOs 6 authentification method
else
[localPlayer authenticateWithCompletionHandler:^(NSError *error) {
if (localPlayer.isAuthenticated)
{
_name = [localPlayer.displayName UTF8String];
_userId = [localPlayer.playerID UTF8String];
[GKPlayer loadPlayersForIdentifiers:localPlayer.friends withCompletionHandler:^(NSArray *players, NSError *error) {
for (GKPlayer* player in players) {
if ([player isFriend]) {
NSDictionary* dict =
#{#"displayName" : player.displayName,
#"alias" : player.alias,
#"playerID" : player.playerID};
AttrDictionary* playerInfo = [dict hydraAttrDictionary];
SocialFriend* socialfriend = this->getNewFriendInstance(*playerInfo);
this->addFriend(socialfriend);
delete playerInfo;
}
}
this->getDelegate().socialConnectionDidSucceedLogin(*this);
this->setState(connectionLoged);
}];
}
else{
NSString* errorString = [error localizedDescription];
this->getDelegate().socialConnectionDidFailToLogin(*this, std::string([errorString UTF8String]));
this->setState(connectionClosed);
}
}];
I need the code compatible with iOS 6 and iOS 5 so you will see I have the two implementations. For iOS 6 the completion handler returns with an UIViewController null and the error as I say. I'm afraid that in production it happends the same. In the simulator all works fine.
PS- You will find some c++ code, it's because I implement a c++ wrapper for GameCenter as my game is write in cocos2dx...
When someone cancels out of the interface to sign in to game center, it will give you GKErrorCanceled. The third time in a row that they cancel, it will warn them that it will disable game center.
If they do choose to disable game center, then it won't show the interface anymore, and it will just give you GKErrorCanceled instead.
Once game center has been disabled, the only way to sign in is by going into the actual game center app.
The 3 times in a row could be in any app or any combination of apps that use game center, and game center will be disabled for all apps that use game center. The 3 times in a row restarts every time they sign in to game center.
This is for both sandbox and non-sandbox.
This is for both ios 5 and ios 6.

Resources