问题
I have successfully added Game Center capabilities to my app. When the app is opened it successfully authenticates the user and shows the "Welcome back (UserName)" banner.
However, I am not sure of how to add a leaderboard to the game. I was wondering if someone could help me A: Help me understand how to link the leaderboard i made in iTunes connect with the app and make highscore the value of the leaderboard. And B: Make the leaderboard show up in the app with all the rankings.
All the code for gamecenter in my app so far is below.
Interface File:
#import <Foundation/Foundation.h>
#import <GameKit/GameKit.h>
@interface GCHelper : NSObject {
BOOL gameCenterAvailable;
BOOL userAuthenticated;
}
@property (assign, readonly) BOOL gameCenterAvailable;
+ (GCHelper *)sharedInstance;
-(void)authenticateLocalUser;
@end
Implementation File:
#import "GCHelper.h"
@implementation GCHelper
@synthesize gameCenterAvailable;
#pragma mark initialization
static GCHelper *sharedHelper = nil;
+ (GCHelper *) sharedInstance {
if (!sharedHelper) {
sharedHelper = [[GCHelper alloc] init];
}
return sharedHelper;
}
- (BOOL)isGameCenterAvailable {
Class gcClass = (NSClassFromString(@"GKLocalPlayer"));
NSString *reqSysVer = @"4.1";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
BOOL osVersionSupported = ([currSysVer compare:reqSysVer
options:NSNumericSearch] != NSOrderedAscending);
return (gcClass && osVersionSupported);
}
- (id) init {
if ((self = [super init])) {
gameCenterAvailable = [self isGameCenterAvailable];
if(gameCenterAvailable) {
NSNotificationCenter *nc =
[NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:@selector(authenticationChanged)
name:GKPlayerAuthenticationDidChangeNotificationName
object:nil];
}
}
return self;
}
-(void)authenticationChanged {
if ([GKLocalPlayer localPlayer].isAuthenticated && !userAuthenticated) {
NSLog(@"Authentication changed: player authenticated.");
userAuthenticated = TRUE;
} else if (![GKLocalPlayer localPlayer].isAuthenticated && userAuthenticated) {
NSLog(@"Authentication changed: player not authenticated");
userAuthenticated = FALSE;
}
}
#pragma mark User Functions
-(void) authenticateLocalUser {
if(!gameCenterAvailable) return;
NSLog(@"Authentication local user...");
if ([GKLocalPlayer localPlayer].authenticated == NO) {
[[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:nil];
} else {
NSLog(@"Already authenticated!");
}
}
@end
OKAY, so. The code is working now but when the code to access the leaderboard returns an error, I have no code to handle it and instead just makes the app go into a frozen state and makes it unable to function.
Code being called to access leaderboard :
- (void) presentLeaderboards
{
GKGameCenterViewController* gameCenterController = [[GKGameCenterViewController alloc] init];
gameCenterController.viewState = GKGameCenterViewControllerStateLeaderboards;
gameCenterController.gameCenterDelegate = self;
[self presentViewController:gameCenterController animated:YES completion:nil];
}
回答1:
To set up a leaderboard go to iTunes Connect > Manage Your Apps > Your App > Manage Game Center > Add Leaderboard > Single Leaderboard.
Give your leaderboard a name and all of the required organizational information needed.
Add this method to your GCHelper.m
:
-(void) submitScore:(int64_t)score Leaderboard: (NSString*)leaderboard
{
//1: Check if Game Center
// features are enabled
if (!_gameCenterFeaturesEnabled) {
return;
}
//2: Create a GKScore object
GKScore* gkScore =
[[GKScore alloc]
initWithLeaderboardIdentifier:leaderboard];
//3: Set the score value
gkScore.value = score;
//4: Send the score to Game Center
[gkScore reportScoreWithCompletionHandler:
^(NSError* error) {
[self setLastError:error];
BOOL success = (error == nil);
if ([_delegate
respondsToSelector:
@selector(onScoresSubmitted:)]) {
[_delegate onScoresSubmitted:success];
}
}];
}
And add this to your GCHelper.h
:
-(void) submitScore:(int64_t)score Leaderboard: (NSString*)leaderboard;
Now in the .m for your game add this method to whatever method you call when the game is over:
[[GCHelper sharedGameKitHelper] submitScore:highScore Leaderboard:LeaderboardName];
In this example highScore
is the int_64
value of your score and LeaderboardName
is an NSString
equal to the Leaderboard Identifier you set up in iTunes Connect. Also be sure to add Game Center capabilities to your application.
After that you should be able to submit high scores!
ALSO ADD THIS TO GCHelper.m
-(void) setLastError:(NSError*)error {
_lastError = [error copy];
if (_lastError) {
NSLog(@"GameKitHelper ERROR: %@", [[_lastError userInfo]
description]);
}
}
AND ALSO ADD THIS TO GCHelper.h
@property (nonatomic, assign)id<GCHelperProtocol> delegate;
Here is my GCHelper.h:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
// Include the GameKit framework
#import <GameKit/GameKit.h>
// Protocol to notify external
// objects when Game Center events occur or
// when Game Center async tasks are completed
@protocol GCHelperProtocol<NSObject>
-(void) onScoresSubmitted:(bool)success;
@end
@interface GCHelper : NSObject
@property (nonatomic, assign)id<GCHelperProtocol> delegate;
// This property holds the last known error
// that occured while using the Game Center API's
@property (nonatomic, readonly) NSError* lastError;
+ (id) sharedGameKitHelper;
// Player authentication, info
-(void) authenticateLocalPlayer;
//Scores
-(void) submitScore:(int64_t)score Leaderboard: (NSString*)leaderboard;
@end
And here my GCHelper.m:
#import "GCHelper.h"
@interface GCHelper ()
<GKGameCenterControllerDelegate> {
BOOL _gameCenterFeaturesEnabled;
}
@end
@implementation GCHelper
#pragma mark Singleton stuff
+(id) sharedGameKitHelper {
static GCHelper *sharedGameKitHelper;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedGameKitHelper =
[[GCHelper alloc] init];
});
return sharedGameKitHelper;
}
#pragma mark Player Authentication
-(void) authenticateLocalPlayer {
GKLocalPlayer* localPlayer =
[GKLocalPlayer localPlayer];
localPlayer.authenticateHandler =
^(UIViewController *viewController,
NSError *error) {
[self setLastError:error];
if (localPlayer.authenticated) {
_gameCenterFeaturesEnabled = YES;
} else if(viewController) {
[self presentViewController:viewController];
} else {
_gameCenterFeaturesEnabled = NO;
}
};
}
#pragma mark Property setters
-(void) setLastError:(NSError*)error {
_lastError = [error copy];
if (_lastError) {
NSLog(@"GameKitHelper ERROR: %@", [[_lastError userInfo]
description]);
}
}
#pragma mark UIViewController stuff
-(UIViewController*) getRootViewController {
return [UIApplication
sharedApplication].keyWindow.rootViewController;
}
-(void)presentViewController:(UIViewController*)vc {
UIViewController* rootVC = [self getRootViewController];
[rootVC presentViewController:vc animated:YES
completion:nil];
}
#pragma mark Scores
- (void) reportAchievementWithID:(NSString*) AchievementID {
[GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements, NSError *error) {
if(error) NSLog(@"error reporting ach");
for (GKAchievement *ach in achievements) {
if([ach.identifier isEqualToString:AchievementID]) { //already submitted
return ;
}
}
GKAchievement *achievementToSend = [[GKAchievement alloc] initWithIdentifier:AchievementID];
achievementToSend.percentComplete = 100;
achievementToSend.showsCompletionBanner = YES;
[achievementToSend reportAchievementWithCompletionHandler:NULL];
}];
}
-(void) submitScore:(int64_t)score Leaderboard: (NSString*)leaderboard
{
//1: Check if Game Center
// features are enabled
if (!_gameCenterFeaturesEnabled) {
return;
}
//2: Create a GKScore object
GKScore* gkScore =
[[GKScore alloc]
initWithLeaderboardIdentifier:leaderboard];
//3: Set the score value
gkScore.value = score;
//4: Send the score to Game Center
[gkScore reportScoreWithCompletionHandler:
^(NSError* error) {
[self setLastError:error];
BOOL success = (error == nil);
if ([_delegate
respondsToSelector:
@selector(onScoresSubmitted:)]) {
[_delegate onScoresSubmitted:success];
}
}];
}
-(void) gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController
{
//nothing
}
@end
来源:https://stackoverflow.com/questions/24967767/game-center-in-ios-7-leaderboard