I'm trying to make a Game Center leaderboard for my app. I've been following the steps from Apple and following the sample code from GKTapper, but I can't get any scores to show in Game Center. I've set up the leaderboard in iTunes Connect. Here's the code that reports the score:
- (void) reportScore: (int64_t) score forCategory: (NSString *) category {
GKScore *scoreReporter = [[[GKScore alloc] initWithCategory:category] autorelease];
scoreReporter.value = score;
[scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
if (error != nil)
{
UIAlertView* alert= [[[UIAlertView alloc] initWithTitle: #"Score Report Failed!" message: [NSString stringWithFormat: #"Reason: %#", [error localizedDescription]] delegate: self cancelButtonTitle: #"Try Again..." otherButtonTitles: NULL] autorelease];
[alert show];
}
}];
}
The code seems to run fine. The alert is never shown. But, when I go into Game Center, the leaderboard is blank. I'm running Xcode 4.2 and iOS 5. Any ideas?
Whatever's been told is completely true :
you need an int_64t score;
you need all things set up on iTunesConnect;
you need to use a sandbox account.
What I have just found out is that there's no such thing in iTunesConnect as the Category. On the other hand, you're supposed to init your GKScore with the leaderboard category.
From what i've seen over the forums, about 2/3 of the people get it right.
In iTunesConnect, when you configure a leaderboard, you set :
its reference (which i long thought was the category);
its ID (which turns out to be the actual category).
I was trying to post score using the reference instead of the ID.
Two things :
first, i had no error from the program (which, in some way, is acceptable);
second, once i got it right, i notice that, whereas many people claim the opposite, there's no need for more than one sandbox account to display the score.
Setting the category explicitly again after the init fixed it for me.
Scoreobject.category = category
Also to show the right leaderboard I set the category there aswell.
leaderboardobject.category = #"mycategory";
1) Please check if you have spelled the category correctly. Surprisingly, I was not getting an error even when I had my category misspelled. Correcting the typo fixed the issue for me.
2) Please check if you are setting the right Leaderboard before presenting the GKLeaderboardViewController? Set it correctly as below:
GKLeaderboardViewController *leaderboardViewController = [[[GKLeaderboardViewController alloc] init] autorelease];
leaderboardViewController.category = #"yourcategoryname";
[youviewcontroller presentModalViewController:leaderboardViewController animated: YES];
Two verified GameCenter users must have reported scores to a leaderboard before any scores show up in the leaderboard.
If you've only got one user in your Sandbox, create another and report a score.
If it's still not working, make sure that you verified the email address of both users.
The documentation for reportScoreWithCompletionHandler says :
"Your application should keep a strong reference to the score object until the reporting task is complete."
You are autoreleasing. Since the task will complete later, the object is probably deleted before the operation is executed.
Related
Posted this on Apple with no luck, but now that the iOS 6 NDA is up, hoping more eyes will see it here.
I am attempting to modify an app to only allow a user to select music that has been downloaded locally. I have the following code under iOS 6 GM:
MPMediaPickerController* mpc = [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeAnyAudio];
mpc.allowsPickingMultipleItems = YES;
mpc.modalPresentationStyle = UIModalPresentationCurrentContext;
mpc.showsCloudItems = NO;
[self presentViewController:mpc animated:YES completion:nil];
From the documentation:
The default behavior for a media item picker is YES, which means the
the picker shows available iCloud items. A media item is considered an
iCloud item if it is available via iTunes Match and is not already
stored on the device.
I take this to mean that if iTunes Match is enabled, only items that have been downloaded to the device will show in the picker, however I always see the entire iTunes Match library. I filed a radar for this, because it seems like a serious bug. If anyone can tell me otherwise, I'd love to know what I'm missing here.
This seems to be an OS problem.
Using picker.showsCloudItems = NO; correctly shows fewer songs, instead of the whole list... The songs listed there are songs that either were manually downloaded in the Music app or songs that were streamed and therefore cached.
The problem, at least in my case, is dealing with the cached ones.
If I select a song that was manually downloaded the value of MPMediaItemPropertyIsCloudItem is NO, which is correct. I can also access the asset's URL through the MPMediaItemPropertyAssetURL property.
On the other hand, selecting a song that was cached returns YES on MPMediaItemPropertyIsCloudItem and nil on MPMediaItemPropertyAssetURL, making the song virtually useless to me.
Sorry I don't have an actual answer but I don't have enough reputation to simply comment.
Hope my 2 cents help somehow, but it truly seems to me that this issue can only be resolved by Apple in a future update.
A better solution to test if an item comes from iCloud in the didPickMediaItems delegate:
MPMediaItem *selectedItem = [selectedItems objectAtIndex:0];
if (![[selectedItem valueForProperty:MPMediaItemPropertyIsCloudItem] boolValue])
You don't really need to play it, it is more efficient to use the embedded property in the MPMediaItem.
I had this same problem. Although I was unable to hide the items, here's a good workaround that I used to prevent people from being able to select them. Inside didPickMediaItems, you should temporarily load it into an AVPlayerItem and then just check the validity of that item like so:
- (void)mediaPicker:(MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection
{
MPMediaItem *selectedItem = [[mediaItemCollection items]objectAtIndex:0];
NSURL *tempURL = [selectedItem valueForProperty:MPMediaItemPropertyAssetURL];
AVPlayerItem *playerItem = [[AVPlayerItem alloc]initWithURL:tempURL];
if(playerItem.loadedTimeRanges==NULL)
{
UIAlertView *alert=[[[UIAlertView alloc]initWithTitle:NSLocalizedString(#"Invalid Song Choice",NULL) message:NSLocalizedString(#"Please choose a song that is local to your phone.",NULL) delegate:self cancelButtonTitle:NSLocalizedString(#"Okay",NULL) otherButtonTitles:nil]autorelease];
[alert show];
[playerItem release];
}
else
{
NSLog(#"Your good to go...do whatever you want with the local song");
}
}
It appears to be fixed in iOS 7.
The following code works; iCloud items are not showing:
MPMediaPickerController *picker = [[MPMediaPickerController alloc] initWithMediaTypes: MPMediaTypeMusic];
picker.delegate = self;
picker.allowsPickingMultipleItems = NO;
picker.showsCloudItems = NO;
I have a little game with achievements support. The game has not been published yet, but I need to test achievements. I can do it now but just partially, for example when I execute game center application it seems it allways run in sandbox mode and this game is not listed in the Games tab. So, I can't see if the achievement achieved where ok or not. Is there any way to check this information for a wip in progress game?.
Thanks in advance.
You could check that by presenting the standard achievements interface, that will show you all the achievements defined for the game that are not hidden and which ones have been completed by the current logged in user. You should put something similar to this on your ViewController and invoke it as the target of a button for example:
- (void)showAchievements{
GKAchievementViewController *achievements = [[GKAchievementViewController alloc] init];
if (achievements != nil){
achievements.achievementDelegate = self;
[self presentModalViewController: achievements animated: YES];
}
[achievements release];
}
Your ViewController should implement the GKAchievementViewControllerDelegate protocol.
I have spent the last 2 days fighting trying to get in app purchases working! The app has not been approved by Apple (its not ready yet), so I just did the Developer Pulled Binary method. I added a non-consumable (and I am pretty sure my contracts are cleared) and called it com.MYAPP.MYAPPNAME.levelone
I am using the MKStoreKit 3.1 relevant
I just want to see that the item will appear in the NSLog for the app, so I have this in my App Delagate
- (void) applicationDidFinishLaunching:(UIApplication*)application
{
[MKStoreManager sharedManager];
[[MKStoreManager sharedManager] purchasableObjectsDescription];
...
When I run this it just tells me
Problem in iTunes connect configuration for product: com.mycompany.myapp.005
Problem in iTunes connect configuration for product: com.mycompany.myapp.featureA
This is a Cocos2d based game if it makes any difference.
There are reasons why I didn't implement MKStoreManager to accept a set of products as parameters.
1) You should not litter your code with hard coded product ids. This is because you initiate a purchase request with a product id. The former happens on AppDelegate and the latter happens on one of your view controllers. So there should be some file where you put in all those product constants. Why not use MKStoreManager.h itself for that?
MKStoreKit 3.1 requires some configuration before you use it; it doesn't just work out of the box.
Specifically, you need to tell MKStoreKit the list of features/product identifiers that you have configured in iTunes Connect. Oddly, you do that by modifying the source code, instead of passing in an array of arguments.
Examine MKStoreManager.h lines 26-34:
// CONFIGURATION STARTS -- Change this in your app
define kConsumableBaseFeatureId #"com.mycompany.myapp."
#define kFeatureAId #"com.mycompany.myapp.featureA"
#define kConsumableFeatureBId #"com.mycompany.myapp.005"
// consumable features should have only number as the last part of the product name
// MKStoreKit automatically keeps track of the count of your consumable product
#define SERVER_PRODUCT_MODEL 0
// CONFIGURATION ENDS -- Change this in your app
You have to change that stuff. If you don't, you'll get errors like the one you posted.
But that's not the only place. You also have to update the requestProductData implementation function in MKStoreManager.m, where kFeatureAId and kConsumableFeatureBId are used.
-(void) requestProductData
{
SKProductsRequest *request= [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObjects:
kFeatureAId,
kConsumableFeatureBId,
nil]];
request.delegate = self;
[request start];
}
You have to specify the product identifier list yourself; MKStoreKit can't guess it for you.
Still, it's weird. It makes you wish MKStoreKit would just accept an array of product identifiers in its initializer!
Remove the unused products inside MKStoreManager.m as follows
-(void) requestProductData
{
SKProductsRequest *request= [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithObjects:
kFeatureAId,
//kConsumableFeatureBId,
nil]];
request.delegate = self;
[request start];
}
I am testing my app on a ipod Touch 4g iOS 4.2. Please note I tested the app on an iphone 2G with iOS 4.2 and this was not an issue.
The initial OpenFeint approval view launches, but the Phonegap view immediately lauches soon after so that the user has no time to enable/ignore Openfeint.
Even worse, the top of the phonegap view is clipped off and you can see the the Openfeint approval screen sitting there behind it.
I can use the app and openfeint works in offline mode registering high score and achievements.
My impression of Openfeint is that its view should go straigh to the top whenever it launches but for some reason it's not happening here.
I'm trying a few UIView methods and property changes but no luck so far.
Anyone come across this or understand how either of the view systems work.
I'll continue my debugging and report back but let me know if anyone out there has a good idea and/or insight.
Thanks
Nigel
I think worked this out. May be a few bugs. Require more thorough testing. Will report back.
Basically I disabled the default Openfeint Approval process and set up my own one using the OpenfeintDelegate.h
(BOOL)showCustomOpenFeintApprovalScreen
{
SCNetworkReachabilityRef reach = SCNetworkReachabilityCreateWithName(kCFAllocatorSystemDefault, "google.com");
SCNetworkConnectionFlags flags;
SCNetworkReachabilityGetFlags(reach, &flags);
if(kSCNetworkReachabilityFlagsReachable & flags) {
// The internet can be accessed using the current connection.
UIAlertView *alert = [ [UIAlertView alloc] initWithTitle:#"OpenFeint Approval"
message:#"Do you want the awesome leaderboard, acheivement and challenge features offered by OpenFeint? (Remember this data will be stored on OpenFeint servers)"
delegate:self
cancelButtonTitle:#"No thanks"
otherButtonTitles:#"Yes", nil
];
[alert show];
[alert release];
}
return YES;
}
I am currently integrating facebook and twitter for iphone with gigya.
For Twitter sometimes its sharing and sometimes don't. Facebook also happening same as well.
lately facebook not even opening its login in screen. On device unlike simulator delegate methods like LoginDidFail, DidLogin called more than once.not sure why.
I am not storing any object to store provider info when login happens.
Can you please let me know why this inconsis
This seems like a multi part question.I would need more information to get a clearer understanding. Please provide code snippets if possible. Meanwhile, please see see my responses below:
Inconsistent Sharing
This might be something to do with how your userAction is being defined.
(http://wiki.gigya.com/030_API_reference/010_Client_API/010_Objects/UserAction_object)
Login Screen not loading
Typically this is down to social Network Applications not set up correctly.
(http://wiki.gigya.com/035_Socialize_Setup/005_Opening_External_Applications)
Event Delegate methods called repeatedly
This may be down do multiple instances of the GSAPI class.
Hope that helps.
I am using following code snippet
GSAPI *gsAPI // declared this in header file
gsAPI = [[GSAPI alloc] initWithAPIKey:XX viewController:self]; // i kept this in viewDidload
// add this code to have facebook and twitter on provider list. this was put in in one method which will be called when user tries to share
GSDictionary *pParams5 = [[GSDictionary new] autorelease]; [pParams5 putStringValue:#"facebook,twitter" forKey:#"enabledProviders"];
[gsAPI showAddConnectionsUI:pParams5 delegate:self context:nil];
//this method called when login fails -(void)gsLoginUIDidFail:(int)errorCode errorMessage:(NSString*)errorMessage context:(id)context {
}
// this method called on successful login
- (void) gsLoginUIDidLogin:(NSString*)provider user:(GSDictionary*)user context:(id)context {
GSDictionary *userAction = [[GSDictionary new] autorelease];
[userAction putStringValue:#"title" forKey:#"title"];
[userAction putStringValue:#"userMessage" forKey:#"userMessage"];
[userAction putStringValue:#"desc" forKey:#"description"];
[userAction putStringValue:#"imageurl" forKey:#"linkBack"];
GSDictionary *pParams5 = [[GSDictionary new] autorelease];
[pParams5 putGSDictionaryValue:userAction forKey:#"userAction"];
[gsAPI sendRequest:#"socialize.publishUserAction" params:pParams5 delegate:self context:nil];
}
-(void) gsDidReceiveResponse:(NSString*)method response:(GSResponse*)response context:(id)context {
//showing alert messages on successful sharing
//this method getting called more than twice on device
}