0
votes

I'm creating a game with two View Controllers and I'm trying to implement GameCenter to my game. I'm authenticating local player in Second View Controller, and there is no such coding for game center in my "first view controller', 'Play game' button on the "First View Controller" is linked by action segue 'modal' to the second view controller, and 'Exit' button on the "Second View Controller" takes the game back to "First View Controller".

Now the problem is that whenever I play the game and make a high score my score is reported perfectly to game center leaderboard , but every time i switch between the two view controllers using 'Play Game' or 'Exit' button, no more score is reported to game center even if i make highscore, I am stuck here and i cant find my mistake, If i terminate my game with spring board and close it, same happens next time I start game and score is only reported first time but no score reported to game center when I move between the two view controllers.

Here is my SecondViewController.m file coding

@interface SecondViewController ()

@property (nonatomic) int64_t score;
@property (nonatomic) BOOL gameCenterEnabled;
@property (nonatomic, strong) NSString *leaderboardIdentifier;
-(void)reportScore;
-(void)authenticateLocalPlayer;
-(void)showLeaderboardAndAchievements:(BOOL)shouldShowLeaderboard;
@end

@implementation SecondViewController

-(void)authenticateLocalPlayer {
    GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];

    localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error) {
    if (viewController != nil) {
        [self presentViewController:viewController animated:YES completion:nil];
    }
    else {
        if ([GKLocalPlayer localPlayer].authenticated) {
            _gameCenterEnabled = YES;

            // Get the default leaderboard identifier.
            [[GKLocalPlayer localPlayer] loadDefaultLeaderboardIdentifierWithCompletionHandler:^(NSString *leaderboardIdentifier, NSError *error) {

                if (error != nil) {
                    NSLog(@"%@", [error localizedDescription]);
                }
                else{
                    _leaderboardIdentifier = leaderboardIdentifier;
                }
            }];
        }
        else{
            _gameCenterEnabled = NO;
        }
    }
};
}

-(void)showLeaderboardAndAchievements:(BOOL)shouldShowLeaderboard {
    GKGameCenterViewController *gcViewController = [[GKGameCenterViewController alloc] init];

    gcViewController.gameCenterDelegate = self;

     if (shouldShowLeaderboard) {
         gcViewController.viewState = GKGameCenterViewControllerStateLeaderboards;
         gcViewController.leaderboardIdentifier = _leaderboardIdentifier;
     }
     else {
         gcViewController.viewState = GKGameCenterViewControllerStateAchievements;
     }

     [self presentViewController:gcViewController animated:YES completion:nil];
}

-(void)gameCenterViewControllerDidFinish:(GKGameCenterViewController    *)gameCenterViewController {
    [gameCenterViewController dismissViewControllerAnimated:YES completion:nil];
}

-(void)reportScore {
    GKScore *score = [[GKScore alloc] initWithLeaderboardIdentifier:_leaderboardIdentifier];
    score.value = _score;

        [GKScore reportScores:@[score] withCompletionHandler:^(NSError *error) {
        if (error != nil) {
            NSLog(@"%@", [error localizedDescription]);
        }
    }];
}

These two buttons for reporting score and viewing leaderboard

- (IBAction)HandleReportScore:(id)sender {
    [self reportScore];
}

- (IBAction)LabelShowLeaderboard:(id)sender {
    [self showLeaderboardAndAchievements:YES];
}

My score method is this and I call this method when i need to increase score in my game

-(void)Score {
    _score += 20;
}

In view did load I am authenticating the local player

- (void)viewDidLoad {
    [super viewDidLoad];

    [self authenticateLocalPlayer];
    [self initValues];
    _gameCenterEnabled = NO;
    _leaderboardIdentifier = @"";
}

And here is the initial values method for score which I called in view did load

-(void)initValues{
// Set the initial values to all member variables.
    _score = 0;
}

@end

No errors show up on build, but the score isn't reported. How can I fix this?

1
Could you try adding this line in reportScore function? NSLog(@"ID is : %@",_leaderboardIdentifier);EDUsta
if score reported first time successfully then problem is not of reporting score. call [self reportScore]; whenever you want to report score.Max
@EDUsta I have tried adding this line into reportScore function but didnt work, Every thing is same as before,user3820375
@Max 2014-07-25 15:19:05.525 Angry Parrot[30587:90b] ID is : My_Best_Flight 2014-07-25 15:19:24.727 Angry Parrot[30587:90b] ID is : 2014-07-25 15:19:37.602 Angry Parrot[30587:90b] ID is : When first time score is reported the output window says ID is My_Best_Flight that means score is reported to leaderboard but as you see next two times no score is reported.. Please helpuser3820375
@EDUsta Do I have to connect both view controllers with the same .h and .m files ? maybe when I move away from a view controller , the local player is no more authenticated ? and thats why no score is reported ? please helpuser3820375

1 Answers

0
votes

For temporary solution, you can directly use @"My_Best_Flight" :

GKScore *score = [[GKScore alloc] initWithLeaderboardIdentifier:@"My_Best_Flight"];

For persistent solution, I would advise to use static string for ID;

@implementation SecondViewController

static NSString* leaderboardID;

-(void)authenticateLocalPlayer{ ...

And;

 if (error != nil) {
     NSLog(@"%@", [error localizedDescription]);
 } else {
     leaderboardID = leaderboardIdentifier;
 }

Lastly;

-(void)reportScore {
    GKScore *score = [[GKScore alloc] initWithLeaderboardIdentifier:leaderboardID];
    score.value = _score;
}

If you don't want any static declarations, you can create a singleton class for ID and score(maybe), but IMO it would be an overkill for saving only a string.

P.S: You should also check your score's value before submitting.