Not able to find players with GKMatchmakerViewController - ios

I am trying to integrate Game Center for matching players. I am using that very simple function:
- (void)findOpponent {
GKMatchRequest* request = [[GKMatchRequest alloc] init];
request.minPlayers = 2;
request.maxPlayers = 2;
GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc]
initWithMatchRequest:request];
mmvc.matchmakerDelegate = self;
[[self viewController] presentViewController:mmvc animated:YES completion:nil];
}
I do have some callback, never called tho':
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)theMatch {
NSLog(#"he");
[[self viewController] dismissViewControllerAnimated:NO completion:nil];
GKMatch* match = theMatch;
[match setDelegate:self];
NSLog(#"Ready to start match!");
}
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindPlayers:(NSArray *)playerIDs {
NSLog(#"Super he");
}
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didReceiveAcceptFromHostedPlayer:(NSString *)playerID {
NSLog(#"Wow");
}
When I test onmy device (wether iPhone or iPad), both using iOS 7.1, I can open Game Center from my Application, but as soon as I click on "Play Now" I instantaneously get the error: "Failed to find players". Yet none of my callback seems to get triggered in my code. Any idea of what I am doing wrong? I did try to reset my iPad settings, logging off from iCloud, rebooting my device, etc.

Fixed.
More than creating a Provisioning Profile and enabling Game Center inside, you also need to Add your app on iTunes Connect.
You need to go to an extremely strange process where it ask for the release date of your app, the price, some screen shots and icons, but once done you will be able to enable Game Center for real.

Related

ios UIImagePickerController delay switching to front camera in the first time

I have implemented to launch UIImagePickerController to capture picture. At the first time, rear camera appear fast, then I switch to front camera, it responses very slowly. It seems to take me nearly 15 seconds. I don't know why initing front camera so slow.
Here my code
UIImagePickerController * _picker = nil;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
_picker = [[[UIImagePickerController alloc] init] autorelease];
_picker.delegate = self;
_picker.allowsEditing = NO;
_picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:_picker animated:YES];
}
UPDATE: My device is iPad 2 (iOS 7.0), I also test Facebook app on my device, it responses immediately when I switch to front camera. When I test my app on Ipad mini (iOS 6.1.3), it works very well, this problem doesn't happen. Can someone figure me out, it's little missing when initialize UIImagePickerController, I suppose.
UPDATE 2: I wrote an another very simple project. It launches an UIImagePickerController immediately on viewDidLoad of the rootViewController and it works well, UIImagePickerController responses instantly when I switch to front camera. Does anyone have idea for it?
Do this on new thread would cancel the delay on open url. I bet it is the same delay.
Note: Not yet tested on camera.
[NSThread detachNewThreadSelector:#selector(openbrowser_in_background:) toTarget:self withObject:Object];
- (void)openbrowser_in_background:(NSString *)url
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: url]];
}
And you might like to change the openURL to
[self presentModalViewController:_picker animated:YES];

GKMatchMaker invite handler deprecated

I have the following code that I have been using before to handle invitations:
[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite) {
// Insert game-specific code here to clean up any game in progress.
if (acceptedInvite) {
GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc] initWithInvite:acceptedInvite];
mmvc.matchmakerDelegate = self;
[self presentViewController:mmvc animated:YES completion:nil];
}
};
However, now it has become deprecated in iOS 7. Where and how do I register a GameKit invite handler in my project?
GKInviteEventHandler to the rescue, and in particular take a look at GKLocalPlayerListener.
Conform to the GKLocalPlayerListener protocol and you should be OK. Below are the protocol methods, which look to be the intended replacement for invitationHandler, but split up in two parts.
- (void)player:(GKPlayer *)player didAcceptInvite:(GKInvite *)invite
- (void)player:(GKPlayer *)player didRequestMatchWithPlayers:(NSArray *)playerIDsToInvite
After you set up some object to conform to that, you just make a call to registerListener:.
[[GKLocalPlayer localPlayer] registerListener:yourObjectHere]
Don't worry about registering it as soon as possible, as the system caches the invites/challenges/turn based stuff, if there's no one to handle those and lets your listener know as soon as you set it up.
As Sam says the new way to do this is with the GKLocalPlayerListener protocol. The approach is reversed now. In the past you issued invitations to other players from part of your app. The other part listened for an invitation from another player and responded to that. Now, you use a matchMakerViewController or Game Center to issue invitations (as before) but now you listen for the acceptance of those invitations. After that Game Center calls didFindMatch to get everything started. If you are in receipt of an invitation Game Center starts your game and then calls didFindMatch to start it up.
This is my code:
In my .h file the GKLocalPlayerListener protocol:
#interface MNFStartupViewController : UIViewController<ADBannerViewDelegate, GKMatchmakerViewControllerDelegate, GKMatchDelegate, GKLocalPlayerListener, UIAlertViewDelegate>
in the .m file in my authenticateHandler block after the local player is authenticated:
[[GKLocalPlayer localPlayer] registerListener:self];
Then the method to listen for the acceptance of an invite:
-(void)player:(GKPlayer *)player didAcceptInvite:(GKInvite *)invite{
//Called when another player accepts a match invite from the local player.
NSLog(#"didAcceptInvite was called: Player: %# accepted our invitation", player);
GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc] initWithInvite:invite];
mmvc.matchmakerDelegate = self;
[self presentViewController:mmvc animated:YES completion:nil];}
Now the method to start the game from Game Center with a set of players chosen in Game Center. This is hard to debug because you cannot start the game in Game Center whilst running it from Xcode at the same time (I don't think so anyway!) so there is a debugging AlertView that can be dropped.
-(void)player:(GKPlayer *)player didRequestMatchWithPlayers:(NSArray *)playerIDsToInvite{
//Called when the local player starts a match with another player from Game Center
//Start of debugging logging and alerting
NSLog(#"In didRequestMatchWithPlayers for players: %#", playerIDsToInvite);
NSString *logString = [[NSString alloc] initWithFormat:#"didrequestMatchWithPlayers was called with player IDs: %#", playerIDsToInvite];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Logging Alert" message:logString delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
//End of debugging logging and alerting
//Create a match for the chosen players
GKMatchRequest *match = [[GKMatchRequest alloc]init];
match.playersToInvite = playerIDsToInvite;
//Create a matchmaking viewcontroller for that match
GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc]initWithMatchRequest:match];
mmvc.matchmakerDelegate = self;
[self presentViewController:mmvc animated:YES completion:nil];}
This is a method to kick off the whole matchmaking process:
-(IBAction)setupMatch:(id)sender{
GKMatchmakerViewController *matchViewController = [[GKMatchmakerViewController alloc] initWithMatchRequest:matchRequest];
matchViewController.matchmakerDelegate = self;
[self presentViewController:matchViewController animated:YES completion:nil];}
Finally this is the method called by Game Center to set the match going when all the players are connected and ready to go. currentPlayer, currentMatch and hostingPlayer are my own properties with obvious uses.
-(void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)match{
//Called when GameCenter completes the auto matchmaking process
match.delegate = (id)self;
[self setCurrentMatch:match];
[self setCurrentPlayers:match.playerIDs];
NSLog(#"Match was found with players: %#, time to get on with the game.", self.currentPlayers);
//Use the built in features to decide which device should be the server.
self.hostingPlayer = [self chooseHostingPlayerIDfromPlayerIDs:self.currentPlayers];
[self dismissViewControllerAnimated:YES completion:nil];}
Hope it helps.
Also, invites only work on the devices. I could not get invites to work in the simulator in iOS 8.1.
I believe the answer is, annoyingly, different for a GKMatch and a GKTurnBasedMatch.
For a GKTurnBasedMatch the invitation counts as a turn event, and is handled in this function:
player(_ player: GKPlayer, receivedTurnEventFor match: GKTurnBasedMatch, didBecomeActive: Bool)
That's inside the GKLocalPlayerListener protocol. You have to have officially registered GKLocalPlayerListener instance with your local player for this to work, so you can only do it after authentication.
...and it doesn't always work. Game Center is unreliable. But it does work sometimes, and that's... something?

Direct link to app-store application in iOS 7

I have a free version of app. And there is a link to a full version in free app.
The link works fine in iOS 6. But in iOS 7 it shows a blank page.
Any help is appreciated!
The link I use:
- (void) getFull
{
[self hideAnimated];
NSString *iTunesLink = #"http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=604760686&mt=8";
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:iTunesLink]];
}
Pretty strange link you are using. I use:
http://itunes.apple.com/app/id<APP_ID>?mt=8
and everything works...
In apps supporting iOS6 and above, I suggest furthermore the use of StoreKit, so you can display your app page in the App Store without leaving your app. You can do that like this:
- (void)productViewControllerDidFinish:(SKStoreProductViewController *)viewController
{
[viewController dismissViewControllerAnimated:YES completion:nil];
}
- (void)showAppWithIdentifier:(NSNumber *)identifier
{
if ([SKStoreProductViewController class]) {
SKStoreProductViewController *controller = [[SKStoreProductViewController alloc] init];
controller.delegate = self;
[controller loadProductWithParameters:#{ SKStoreProductParameterITunesItemIdentifier : identifier }
completionBlock:NULL];
[self presentViewController:controller animated:YES completion:nil];
return;
}
// Fall back to opening App Store for iOS 5.
... open the link as you are already doing
}
Try this one, it's the new syntax with iOS 7 and replace APP_ID by your application's AppID.
itms-apps://itunes.apple.com/app/idAPP_ID
You can refer to this link and this one for more information and discussion about that.

Receiving production ads and interstitials from AdMob in test mode

I'm testing AdMob ads in my iOS-application. AdMob seems to ignore the test-flag I put in the code:
-(IBAction)quitButtonHit:(id)sender{
[[AudioPlayer sharedManager] stopSound];
[self.timer invalidate];
interstitial_ = [[GADInterstitial alloc] init];
interstitial_.adUnitID = adMobUnitID;
interstitial_.delegate = self;
GADRequest *request = [GADRequest request];
request.testing = YES;
[interstitial_ loadRequest:[GADRequest request]];
}
-(void) interstitial:(GADInterstitial *)ad didFailToReceiveAdWithError:(GADRequestError *)error {
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void) interstitialDidDismissScreen:(GADInterstitial *)ad {
[self dismissViewControllerAnimated:YES completion:nil];
}
-(void) interstitialDidReceiveAd:(GADInterstitial *)ad {
[ad presentFromRootViewController:self];
}
I am receiving production interstitials when I hit the Quit-button in my app. I do not understand why since Google states that they will invite you to be able to receive interstitials and because I set the test-flag on the request.
I am also receiving production ads in my app's AdMob banner. But that only goes for my device - on the simulators test ads are displayed. I also set the test-flag when requesting banners.
I would like the production ads to go away, so I won't have to worry about tapping them by accident.
I use AdMob's lates API (version 6.3.0). My deployment target is iOS 6.0.
Can anyone explain this and maybe suggest a solution to make the production ads go away?
Thanks!
Try this :
request.testDevices =
[NSArray arrayWithObjects:
// TODO: Add your device/simulator test identifiers here. They are
// printed to the console when the app is launched.
nil];

Twitter no longer working after Cocos2d 2.0 upgrade

I have a project that uses the Twitter API to Tweet the users high score. That project is written using Cocos2d v1.1 and everything is working fine. I recently started a new project using Cocos2d v2.0 and attempted to use the same code from my other project to incorporate the same Twitter functionality but the viewcontroller will not appear when the Tweet button is pressed. Below is the code I'm using...
if ([TWTweetComposeViewController canSendTweet]) // Check if twitter is setup and reachable
{
CCLOG(#"Can Tweet");
TWTweetComposeViewController *tweetViewController = [[TWTweetComposeViewController alloc] init];
// set initial text
NSString *theTweet = #"The message..."];
[tweetViewController setInitialText:theTweet];
// setup completion handler
tweetViewController.completionHandler = ^(TWTweetComposeViewControllerResult result) {
if(result == TWTweetComposeViewControllerResultDone) {
// the user finished composing a tweet
} else if(result == TWTweetComposeViewControllerResultCancelled) {
// the user cancelled composing a tweet
}
[viewController dismissViewControllerAnimated:YES completion:nil];
};
// present view controller
[[[CCDirector sharedDirector] openGLView] addSubview:viewController.view];
[viewController presentViewController:tweetViewController animated:YES completion:nil];
}
else
{
// Twitter account not configured, inform the user
NSLog(#"You can't send a tweet right now, make sure your device has an internet connection and you have at least one Twitter account setup");
}
I've discovered that "openGLView" is now depreciated and I have replaced it with "view". This still does not work. The method is firing though. I've included a CCLOG that return the string "Can Tweet" and that is appearing in the output window. Does anyone have any suggestions on how to get this to work. Let me know if I need to provide more information.
Thanks
Use this code in cocos2d 2.0
AppController * app = (((AppController*) [UIApplication sharedApplication].delegate));
TWTweetComposeViewController *tweetViewController = [[TWTweetComposeViewController alloc] init];
[tweetViewController setInitialText:string];
[tweetViewController setCompletionHandler:^(TWTweetComposeViewControllerResult result) {
dispatch_async(dispatch_get_main_queue(), ^{
{
if (result == TWTweetComposeViewControllerResultDone)
{
//successful
[[NSNotificationCenter defaultCenter] postNotificationName:#"PPTweetSuccessful" object:nil];
}
else if(result == TWTweetComposeViewControllerResultCancelled)
{
//Cancelled
}
}
[app.navController dismissModalViewControllerAnimated:YES];
[tweetViewController release];
});
}];
[app.navController presentModalViewController:tweetViewController animated:YES];

Resources