I call Chartboost interstitial at applicationDidBecomeActive. My game use s Game Center and sometimes GC authorization window pops up under Chartboost interstitial, blocking Chartboost window. Only solution is switch to GameCenter and login there. Is it possible to check what authorization window was shown?
Blocking ads when Game Center login is on screen might be an option! Code works only on iOS6 btw
#interface ChartboostBridge : NSObject<ChartboostDelegate>
#end
#implementation ChartboostBridge
- (BOOL)shouldDisplayInterstitial:(NSString *)location{
NSLog(#"CB shouldDisplayInterstitial for %#",location);
if ([location isEqualToString:#"game_launch"]) {
if( [[GameCenterIos shared ] hasLogInView] ){
return NO;
}
}
return YES;
}
#end
#implementation GameCenterIos
- (BOOL)hasLogInView{
return isViewOnScreen;
}
- (void)login
{
GKLocalPlayer* localPlayer = [GKLocalPlayer localPlayer];
if (localPlayer.isAuthenticated) {
isViewOnScreen=NO;
return;
}
localPlayer.authenticateHandler =
^(UIViewController *viewController,
NSError *error) {
if (localPlayer.authenticated) {
isAuthenticated = YES;
isViewOnScreen=NO;
} else if(viewController) {
NSLog(#"Game Center shows login ....");
isViewOnScreen=YES;
[self presentViewController:viewController];
} else {
NSLog(#"Game Center error or canceled login ....");
//User canceled Login view
isAuthenticated = NO;
isViewOnScreen=NO;
}
};
}
#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];
}
#end
This is and old question but I just had the same problem and found a workaround.
Change the modalPresentationStyle of the gamecenter loggin view (returned by the ios 6 authentication handler) to UIModalPresentationFullScreen.
On iphone the screen doesn't lock when gamecenter loggin and chartboost interstitial appear. Only on Ipad happens. And whats the difference? that in ipad the loggin is not fullscreen. So I tested changing it to fullscreen and now it works without locking =)
Related
I have a simple iOS app which makes use of Game Center. However recently when updating it to iOS 7, I noticed that the authenticate method does not work.
One of the issues is with the code I am using to present the view controller to the user if they need to sign in to game centre, it no longer pops up the game centre login window in the app.
Another issue I have is that I can't find what method to use instead of the deprecated "authenticateWithCompletionHandler".
Here is my code:
-(void)authenticateLocalUser {
GKLocalPlayer.localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error) {
if (GKLocalPlayer.localPlayer.authenticated) {
// Already authenticated
}
else if (viewController) {
[self presentViewController:viewController animated:YES completion:nil];
}
else {
// Problem with authentication, probably bc the user doesn't use Game Center.
}
};
if ([GKLocalPlayer localPlayer].authenticated == NO) {
[[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error) {
[self callDelegateOnMainThread: #selector(processGameCenterAuth:) withArg:NULL error: error];
}];
}
}
Thanks for your time, Dan.
No matter I managed to figure it out in the end. As for 'authenticateWithCompletionHandler', I used this:
[[[UIApplication sharedApplication] keyWindow].rootViewController presentViewController:viewController animated:YES completion:nil];
I have an iOS Application which will load a particular view controller for authentication. However no matter what, the view controller will not load. Below is the code for my method which handles this (This is for a Game Center authentication popup):
-(void)authenticateLocalUser {
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error) {
if (viewController != nil) {
NSLog(#"AUTH VIEW CONTROLLER");
[[[UIApplication sharedApplication] keyWindow].rootViewController presentViewController:viewController animated:YES completion:nil];
}
else if (localPlayer.isAuthenticated) {
NSLog(#"User is authenticated");
}
else {
NSLog(#"Game Center Auth error.");
}
};
}
As you can see, I have followed the official Apple developer documentation. However the output of this method is always:
Game Center Auth Error (Last NSLog).
Why doesn't the view controller ever load? Because I need it to load so that the user can login to Game Center if they haven't done so already.
Thanks for your time, Dan.
It turned out that the issue in the end was to do with the Game Center app itself. I just logged in/out of that and it all worked. I have also now seen this same issue replicated in other iOS apps too which use Game Center.
What is the proper way to handle invitations from other players in iOS 7?
After my view did load on my root View Controller, I'm calling a game center authentication method, after that I'm setup a invitation handler like so:
[[GKLocalPlayer localPlayer] registerListener:self];
My view controller adopt GKLocalPlayerListener and GKInviteEventListener protocols, by the way, what is the best place to register a listener AppDelegate? Maybe or maybe my custom Game Center singleton?
I add a method described in GKInviteEventListener
-(void)player:(GKPlayer *)player didAcceptInvite:(GKInvite *)invite
{
NSLog(#"Invite accepted!");
GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc] initWithInvite:invite];
mmvc.matchmakerDelegate = self;
[self presentViewController:mmvc animated:YES completion:nil];
}
But, game center matchmaker class have such topic: Receiving Invitations From Other Players and method – matchForInvite:completionHandler:
I don't understand how to use it.
So, what I must use and how?
I think you're doing things correctly. I did things the same way, and it works for me. -matchForInvite:completionHandler is deprecated in iOS 7, so I don't do anything with it.
First I set the authentication handler. This is called when my app loads for the first time, you can set it anywhere you like, but it is best to set the handler as soon as possible.
-(void)authenticateLocalPlayer
{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
__weak GKLocalPlayer *blockLocalPlayer = localPlayer;
//Block is called each time GameKit automatically authenticates
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error)
{
[self setLastError:error];
if (viewController)
{
self.authenticationViewController = viewController;
[self disableGameCenter];
}
else if (blockLocalPlayer.isAuthenticated)
{
[self authenticatedPlayer:blockLocalPlayer];
}
else
{
[self disableGameCenter];
}
};
}
If authentication is successful, then I call this method:
-(void)authenticatedPlayer:(GKLocalPlayer*)localPlayer
{
self.isAuthenticated = YES;
[[NSNotificationCenter defaultCenter]postNotificationName:AUTHENTICATED_NOTIFICATION object:nil];
[[GKLocalPlayer localPlayer]registerListener:self];
}
Then I implemented the two listener methods:
(void)player:(GKPlayer *)player didAcceptInvite:(GKInvite *)invite
{
//.... insert some cleanup code here to manage view controllers etc before presenting the matchmakerviewcontroller.
[self presentMatchmakerViewControllerWithInvite:invite];
}
-(void)player:(GKPlayer *)player didRequestMatchWithPlayers:(NSArray *)playerIDsToInvite
{
//......insert some cleanup code for managing view controllers
GKMatchRequest *match = [[GKMatchRequest alloc]init];
match.playersToInvite = playerIDsToInvite;
GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc]initWithMatchRequest:match];
mmvc.matchmakerDelegate = root.viewControllers[0];
[[[[[UIApplication sharedApplication]delegate]window]rootViewController]presentViewController:mmvc animated:YES completion:nil];
}
I have an app that uses GameCenter in a very simple way (just a simple leaderboard with an all time high score). Sometimes when I switch to my app I'll see the notification saying "welcome back to Game Center" but sometimes this notification appears squished like in the following image:
http://i.imgur.com/KOCFIJo.jpg
Does anybody know what might the causing this? Because I have absolutely no idea.
My authentication code which generates the notification banner is fairly standard.
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
[GKLocalPlayer localPlayer].authenticateHandler = ^(UIViewController *viewController, NSError *error) {
// If there is an error, do not assume local player is not authenticated.
if (localPlayer.isAuthenticated) {
// Enable Game Center Functionality
self.gameCenterAuthenticationComplete = YES;
[self enableGameCenter:YES];
gameCenterButton.enabled=true;
} else {
NSLog(#"game center not logged in");
// User has logged out of Game Center or can not login to Game Center, your app should run
// without GameCenter support or user interface.
self.gameCenterAuthenticationComplete = NO;
[self enableGameCenter:NO];
[self presentViewController:viewController animated:true completion:nil ];
gameCenterButton.enabled=false;
}
};
One additional piece of information is that my app is in portrait orientation when this problem occurs. It seems like if I rotate my phone 90 degrees while the banner is showing, it will look normally in landscape but in portrait it looks all squished. Does this help explain it?
I figured it out. I hadn't implemented preferredInterfaceOrientationForPresentation so I did that
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
And also I made sure that supportedInterfaceOrientations returend UIInterfaceOrientationMaskPortrait (note that it returns UIInterfaceOrientationMASKPortrait not just UIInterfaceOrientationPortrait). After that everything worked fine.
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
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];