All
I made a game for the Apple iOS. Now I would like to show my friend list in Apple's Game Center.
How can I show the Game Center friend list of a logged in player on an iPhone, possibly using the UIViewController (which manages the ViewControllers)?
Any help would be appreciated..
Thanks...
To show your Game center friends in your app you can use the below code given.
-(void) retrieveFriends
{
GKLocalPlayer *lp = [GKLocalPlayer localPlayer];
if (lp.authenticated)
{
[lp loadFriendsWithCompletionHandler:^(NSArray *friends, NSError *error)
{
if (friends != nil)
{
[self loadPlayerData: friends];
}
}];
}
}
-(void) loadPlayerData: (NSArray *) identifiers
{
[GKPlayer loadPlayersForIdentifiers:identifiers withCompletionHandler:^(NSArray *players, NSError *error)
{
if (error != nil)
{
// Handle the error.
}
if (players != nil)
{
// Process the array of GKPlayer objects.
}
}];
}
For more reference you can use the Apple Game KIT guide. below is the link to it
http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/GameKit_Guide/Introduction/Introduction.html
Hope it helps..
For a single Block:
-(void)loadPlayerData:(void (^)(NSArray * playerObjects))complete
{
GKLocalPlayer *lp = [GKLocalPlayer localPlayer];
if (lp.authenticated)
{
[lp loadFriendsWithCompletionHandler:^(NSArray *friends, NSError *error)
{
if (friends != nil)
{
[GKPlayer loadPlayersForIdentifiers:friends withCompletionHandler:^(NSArray *players, NSError *error)
{
if (error != nil)
{
// return #[error];
// Handle the error.
}
else
{
complete (players);
}
}];
}
}];
}
}
Related
I'm building a Game Center game in iOS6 and am continuously running into problems with it. The current one has me stumped - Every single time my game tries to authenticate the local player it fails. Every time it is triggering my "disable game center" function and it's driving me crazy.
- (void) disableGameCenter
{
// Write something to disable gamecenter.
// gameCenterAvailable = FALSE;
}
-(void)showAuthenticationDialogWhenReasonable:(UIViewController *)viewController
{
// Pause Tasks Here
// [[[(AppDelegate *)[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:viewController animated:YES completion:nil];
}
- (void) authenticateLocalPlayer
{
localPlayer = [GKLocalPlayer localPlayer];
__weak GKLocalPlayer* weakLocalPlayer = localPlayer;
weakLocalPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error)
{
if (viewController != nil)
{
[self showAuthenticationDialogWhenReasonable: viewController];
}
else if (weakLocalPlayer.isAuthenticated)
{
self.localPlayer = weakLocalPlayer;
}
else
{
[self disableGameCenter];
}
};
}
Forgive me if I'm wrong, but I don't think you are running the authenticate method.
Try this method instead:
- (void) authenticateLocalPlayer
{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
[localPlayer authenticateWithCompletionHandler:^(NSError *error) {
if (localPlayer.isAuthenticated)
{
NSLog(#"Authenticated");
}
else
{
NSLog(#"Not Authenticated");
}
}];
}
I'm trying to implement a real-time multiplayer game with a custom UI (no GKMatchMakerViewController). I'm using startBrowsingForNearbyPlayersWithReachableHandler:
^(NSString *playerID, BOOL reachable) to find a local player, and then initiating a match request with the GKMatchmaker singleton (which I have already initiated).
Here's where I'm having trouble. When I send a request, the completion handler fires almost immediately, without an error, and the match it returns has an expected player count of zero. Meanwhile, the other player definitely has not responded to the request.
Relevant code:
- (void) findMatch
{
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.minPlayers = NUM_PLAYERS_PER_MATCH; //2
request.maxPlayers = NUM_PLAYERS_PER_MATCH; //2
if (nil != self.playersToInvite)
{
// we always successfully get in this if-statement
request.playersToInvite = self.playersToInvite;
request.inviteeResponseHandler = ^(NSString *playerID, GKInviteeResponse
response)
{
[self.delegate updateUIForPlayer: playerID accepted: (response ==
GKInviteeResponseAccepted)];
};
}
request.inviteMessage = #"Let's Play!";
[self.matchmaker findMatchForRequest:request
withCompletionHandler:^(GKMatch *match, NSError *error) {
if (error) {
// Print the error
NSLog(#"%#", error.localizedDescription);
}
else if (match != nil)
{
self.currentMatch = match;
self.currentMatch.delegate = self;
// All players are connected
if (match.expectedPlayerCount == 0)
{
// start match
[self startMatch];
}
[self stopLookingForPlayers];
}
}];
}
Figured it out! I needed to call - (void)matchForInvite:(GKInvite *)invite completionHandler:(void (^)(GKMatch *match, NSError *error))completionHandler in my invitation handler so that both players have the same match data.
I'm trying to make a leaderboard in my game with Game Center. I post the high score like so:
GKScore *myScoreValue = [[[GKScore alloc] initWithCategory:#"grp.high_scores"] autorelease];
myScoreValue.value = self.game.scoreMeter.score;
NSLog(#"Attemping to submit score: %#", myScoreValue);
[myScoreValue reportScoreWithCompletionHandler:^(NSError *error){
if(error != nil){
NSLog(#"Score Submission Failed");
} else {
NSLog(#"Score Submitted");
id appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate displayLeaderBoard:nil];
}
}];
I see "Score Submitted" as expecting, and it brings up the Game Center leaderboard view, but it just reads "No Scores"
I know other people have said you need at least two accounts, but I've tried with three already.
For each account, the game shows up for them in the Game Center App, and when I query for the top ten scores:
- (void) retrieveTopTenScores
{
GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];
if (leaderboardRequest != nil)
{
leaderboardRequest.playerScope = GKLeaderboardPlayerScopeGlobal;
leaderboardRequest.timeScope = GKLeaderboardTimeScopeAllTime;
leaderboardRequest.range = NSMakeRange(1,10);
[leaderboardRequest loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error) {
if (error != nil)
{
NSLog(#"Error grabbing top ten: %#", error);
}
if (scores != nil)
{
NSLog(#"Top ten scores: %#", scores);
}
}];
}
}
each user only sees their own score.
So why is the leaderboard empty, and why is each user only seeing their own score?
Sandbox can be messy sometimes, but let me ask you this. Is your self.game.scoreMeter.score an int?
If so, try doing this:
myScoreValue.value = [[NSNumber numberWithInt:self.game.scoreMeter.score] longLongValue];
for setting the value of the GKScore object. Let me know if it changes anything.
Well, it turns out you need to be signed in to game center with a developer sandbox account for it to work correctly
I have built objectives for my game and everything works just fine accept the part of making the objectives not be called any more after any of them is completed.
I know there is a Property of the GKAchievement Class "completed" which is a boolean that returns yes when the Achievement is 100 percent done.
here is the method that called when a Achievement is 100 percent done it passes id which is the Achievement identifier and report the acheeee :
- (void)AchivmentDidAchive:(id)Achivment{
NSString *identifier = Achivment;
NSLog(#"%#",identifier);
self.achivment = [[GKAchievement alloc]initWithIdentifier:identifier];
self.achivment.showsCompletionBanner = YES;
if (!self.achivment.completed) {
self.achivment.percentComplete = 100;
NSLog(#"Reproting!");
[self.achivment reportAchievementWithCompletionHandler: ^(NSError *error)
{
}];
}
else {
NSLog(#"Achivment Completed!");
} }
what I am trying to do here is to set the percent completed to 100 and report it so in the next time ie want get called again.
but it always works... any better idea for how to handle this?
in interface add variable & property:
NSMutableDictionary *earnedAchievementCache;
#property (nonatomic, retain)NSMutableDictionary *earnedAchievementCache;
in .m:
#synthesize earnedAchievementCache;
- (void) submitAchievement: (NSString*) identifier percentComplete: (double) percentComplete
{
if(self.earnedAchievementCache == NULL)
{
[GKAchievement loadAchievementsWithCompletionHandler: ^(NSArray *scores, NSError *error)
{
if(error == NULL)
{
NSMutableDictionary* tempCache= [NSMutableDictionary dictionaryWithCapacity: [scores count]];
for (GKAchievement* score in scores)
{
[tempCache setObject: score forKey: score.identifier];
}
self.earnedAchievementCache= tempCache;
[self submitAchievement: identifier percentComplete: percentComplete];
}
}];
}
else
{
GKAchievement* achievement= [self.earnedAchievementCache objectForKey: identifier];
if(achievement != NULL)
{
if((achievement.percentComplete >= 100.0) || (achievement.percentComplete >= percentComplete))
{
achievement= NULL;
}
achievement.percentComplete= percentComplete;
}
else
{
achievement= [[[GKAchievement alloc] initWithIdentifier: identifier] autorelease];
achievement.percentComplete= percentComplete;
[self.earnedAchievementCache setObject: achievement forKey: achievement.identifier];
}
if(achievement!= NULL)
{
//Submit the Achievement...
if (achievement.percentComplete>=100) {
//show banner
achievement.showsCompletionBanner = YES; //only in IOS 5+
}
[achievement reportAchievementWithCompletionHandler: ^(NSError *error)
{
if (error!=NULL){
NSLog(#"Error!!");
} else NSLog(#"all is well");
}];
}
}
}
in dealloc :
[self.earnedAchievementCache release];
i'm using the cache to not submit scores already submitted / completed
PS: the code is perfect just copy and paste it into your class and it will work
this is what I use in my helper Game Center class:
-(void) reportAchievementWithID:(NSString*) AchievementID {
[GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements, NSError *error) {
if(error) NSLog(#"error");
for (GKAchievement *ach in achievements) {
if([ach.identifier isEqualToString:AchievementID]) { //already submitted
NSLog(#"Already submitted");
return ;
}
}
GKAchievement *achievementToSend = [[GKAchievement alloc] initWithIdentifier:AchievementID];
achievementToSend.percentComplete = 100;
achievementToSend.showsCompletionBanner = YES;
[achievementToSend reportAchievementWithCompletionHandler:NULL];
}];
}
note: I don't use percentages in my achievements, so you'd need to modify things a little bit if you do.
I'm doing an ios app based on maths..
I've done the code for uploading the high score to the Game Center..
but this doesn't work..
it's always showing 0 as the high score..
This is my code...
[[GKLocalPlayer localPlayer]authenticateWithCompletionHandler:^(NSError *error)
{
if (error ==nil)
{
CCLOG(#"Success");
} else
{
CCLOG(#"Fail");
}
}];
.
.
.
.
.
-(void)showLeaderboard
{
if( ! gameCenterViewController_ )
gameCenterViewController_ = [[GameCenterViewController alloc] init];
[gameCenterViewController_ showLeaderboard];
}
-(void)submitMyScore1:(int)score1
{
CCLOG(#"submitMyScore1--%d",score1);
//This is the same category id you set in your itunes connect GameCenter LeaderBoard
GKScore *myScoreValue = [[[GKScore alloc] initWithCategory:#"bigwizlist"] autorelease];
myScoreValue.value = score1;
[myScoreValue reportScoreWithCompletionHandler:^(NSError *error){
if(error != nil)
{
CCLOG(#"Score Submission Failed");
} else
{
CCLOG(#"Score Submitted");
}
}];
}
I think you need to use an int64_t for your method! I use this method and it works perfectly fine :-)
-(void)submitScore:(int64_t)score category:(NSString*)category{
GKScore *gkScore = [[[GKScore alloc]initWithCategory:category]autorelease];
gkScore.value = score;
[gkScore reportScoreWithCompletionHandler:^(NSError* error)
{
[self setLastError:error];
bool sucess = (error == nil);
[delegate onScoresSubmitted:sucess];
}];
}
Greetings
Anselm