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
Related
I have a issue with the Login and sharing dialogs on my app. About a week ago they started appearing only on Portrait mode (either normal or upside down), but the landscape modes does not work.
NSArray *permissions = #[#"user_photos",
#"user_likes",
#"user_friends",
#"email"];
_loginManager = [[FBSDKLoginManager alloc] init];
_loginManager.loginBehavior = FBSDKLoginBehaviorWeb;
[_loginManager logInWithReadPermissions:permissions fromViewController:self handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if(result.isCancelled || error)
{
[self pressedCancel];
return;
}
NSSet* declinedPermissions = result.declinedPermissions;
for (NSString *declinedPermission in declinedPermissions) {
if(!nullOrEmpty(declinedPermission))
{
[self pressedCancel];
return;
}
}
if ([FBSDKAccessToken currentAccessToken]) {
// self.settings.facebookToken = [FBSDKAccessToken currentAccessToken].tokenString;
// Send data capture
if([EventData sharedInstance].dataCaptureSettings.enabled)
{
[FacebookHelper getUserInfoWithCompletion:
^(NSDictionary* userInfo, NSError* error)
{
if(!nullOrEmpty(userInfo))
{
[self captureData:userInfo];
} else {
[self captureData:nil];
}
[self didSignIn];
}];
return;
} else {
[self captureData:nil];
[self didSignIn];
}
}
}];
Here's a MPOC to replicate the issue:
https://www.dropbox.com/s/p62vajqfk916bz1/FBTest.zip?dl=0
Any ideas what may be causing this? Or how could I make it work on Landscape mode as well?
Thanks!
just in case anyone else has this issue, it was fixed on the newest Facebook SDK for iOS (4.38.1)
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 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.
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);
}
}];
}
}];
}
}
I need to retrieve authenticated player's submited score from Game Center. I use this code to get the score, but it just gets the top score (best score of the leaderboard not the specified player's score). How can I retrieve the authenticated player's score?
- (void) retrievePlayersScore {
GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];
if (leaderboardRequest != nil) {
leaderboardRequest.playerScope = GKLeaderboardPlayerScopeGlobal;
leaderboardRequest.timeScope = GKLeaderboardTimeScopeAllTime;
leaderboardRequest.range = NSMakeRange(1,1);
[leaderboardRequest loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error) {
if (error != nil) {
// handle the error. if (scores != nil)
}
if (scores != nil){
// process the score information.
CCLOG(#"My Score: %d", ((GKScore*)[scores objectAtIndex:0]).value);
}
}];
}
}
You can use the following code:
GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];
leaderboardRequest.identifier = _leaderboardIdentifier;
if (leaderboardRequest != nil) {
[leaderboardRequest loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error){
if (error != nil) {
//Handle error
}
else{
[delegate onLocalPlayerScoreReceived:leaderboardRequest.localPlayerScore];
}
}];
}
You just have to hit loadScoresWithCompletionHandler for a given GKLeaderboard, then automatically board.localPlayerScore will be filled out for that board.
So for example,
- (void) getLoadLeaderboardPositions
{
[GKLeaderboard loadLeaderboardsWithCompletionHandler:^(NSArray *leaderboards, NSError *nsError) {
if( nsError != nil )
{
error( nsError, "get leaderboard score" ) ;
return ;
}
for( GKLeaderboard* board in leaderboards )
{
// fetch score for minimum amt of data, b/c must call `loadScore..` to get MY score.
board.playerScope = GKLeaderboardPlayerScopeFriendsOnly ;
board.timeScope = GKLeaderboardTimeScopeAllTime ;
NSRange range = {.location = 1, .length = 1};
board.range = range ;
[board loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
printf( "YOUR SCORE ON BOARD %s WAS %lld\n", [board.title UTF8String], board.localPlayerScore.value ) ;
}] ;
}
}] ;
}
You may also try to initiate the leader board by using an array of player id(s) in order to narrow the number of players:
GKLeaderboard *board = [[[GKLeaderboard alloc] initWithPlayerIDs:[NSArray arrayWithObject:myGCPlayerID]] autorelease];
Updated version using Swift
let localPlayer = GKLocalPlayer.localPlayer()
if localPlayer.isAuthenticated {
let leaderboard = GKLeaderboard(players: [localPlayer])
leaderboard.identifier = LEADERBOARD_ID
leaderboard.timeScope = .allTime
leaderboard.loadScores(completionHandler: {
(scores, error) in
let bestScore = scores?.first?.value
if bestScore != nil {
// Do something with bestScore
}
})
}