Check for a valid Facebook Session - iphone

I was just checking for the state of FBSession
- (BOOL)hasValidSession {
return (self.session.state == FBSessionStateOpen)
}
Occasionally the state would briefly be changed to FBSessionStateOpenTokenExtended and this would return NO which would bring down my login modal. When I would click connect again it would crash the app for trying to reestablish an active facebook session. So I changed it to
- (BOOL)hasValidSession {
if (self.session.state == FBSessionStateOpen || self.session.state == FBSessionStateOpenTokenExtended) {
return YES;
}
else {
return NO;
}}
My above method works so far but it seems like a hack... What is the best ubiquitous way to check for a valid session in your app?

This is the way I check the facebook session in my app and it works for me:
-(BOOL)checkFacebookSession
{
if([FBSession activeSession].state == FBSessionStateCreatedTokenLoaded)
{
NSLog(#"Logged in to Facebook");
[self openFacebookSession];
UIAlertView *alertDialog;
alertDialog = [[UIAlertView alloc] initWithTitle:#"Facebook" message:#"You're already logged in to Facebook" delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alertDialog show];
[alertDialog release];
return YES;
}
else{
NSLog(#"Not logged in to Facebook");
return NO; //Show login flow.
}
}
Hope it helps! :D

The session is active if the state is either in FBSessionStateOpen or in FBSessionStateOpenTokenExtended. You can use the method below to get the current status of the user is logged in:
- (BOOL)isActiveSession
{
return (FBSession.activeSession.state == FBSessionStateOpen
|| FBSession.activeSession.state == FBSessionStateOpenTokenExtended);
}

Related

How get return value of the RacSignal to

I have a beginner's question regarding the ReactiveCocoa.
I want to return the value of shouldPerformSegueWithIdentifier method based on user interaction with UIAlertView.
That's what I have so far, obviously it doesn't work. How should I proceed?
-(BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender{
if([identifier isEqualToString:ModalBrowser]){
if(self.delegate.currentCoreConversation!=nil){
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:#"Disconnect?" message:#"This action will disconnect you from your current conversation. Would you like to continue?" delegate:self cancelButtonTitle:#"Heck No Techno!" otherButtonTitles:#"Certainly", nil];
[alertView show];
[alertView.rac_buttonClickedSignal subscribeNext:^(NSNumber *x) {
// return [x isEqual:#1];
}];
[alertView.rac_buttonClickedSignal subscribeNext:^(NSNumber *x) {
// return [x isEqual:#1];
}];
}
}
return YES;
}
Alert views don't block the thread of execution when displayed. In other words, the user's tap will arrive after you've already returned from -shouldPerformSegueWithIdentifier:sender:.
Instead of trying to figure out a way to change that behavior, you should return NO immediately, and then programmatically trigger a segue later (after the user has responded to your alert view).

GameCenter Operation cancelled if account never used with game center

I am using GameCenter on my app. I have these lines
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
[localPlayer authenticateWithCompletionHandler:^(NSError *error) {
if (localPlayer.isAuthenticated)
{
}
the problem is that the localPlayer.isAuthenticated flag is always TRUE bur error variable comes with code 2 = "operation was cancelled" (???).
I have sign out from device's game center and from the store but this flag is always true and I do not see the game center sign in that my app should show when it starts. I don't see either the "welcome" banner that always show when a game that uses game center starts.
How do I force a sign out of game center to make the sign in window to show again?
I am compiling for iOS 4.3.
thanks
What I have discovered now is that this happens if you never signed in on device's game center. Once you login there, and say you want to use your username on game center, the app works. The worst part is this: suppose someone downloads the game but does not have the game center set yet. So, the game will never work for them? My game is supposed to work exclusively with game center on. So, for me this is an issue.
For me its working great. Just changed code from
if([GKLocalPlayer localPlayer].authenticated)
To
if([GKLocalPlayer localPlayer].authenticated == NO)
//Other codes
if([GKLocalPlayer localPlayer].authenticated == NO)
{
[[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error)
{
[self processGameCenterAuth: error];
}];
}
- (void) processGameCenterAuth: (NSError*) error
{
if(error == NULL)
{
[mGameCenterManager reloadHighScoresForCategory: self.currentLeaderBoard];
}
else
{
// NSLog(#"%#\n\n",[NSString stringWithFormat: #"Reason: %#", [error localizedDescription]]);
AppController *app = (AppController*)[UIApplication sharedApplication].delegate;
if(!app.isgameCenterStarted)
{
UIAlertView* alert= [[[UIAlertView alloc] initWithTitle:#"Game Center Unavailable" message: #"Player is not signed in"
delegate: NULL cancelButtonTitle: #"OK" otherButtonTitles: NULL] autorelease];
[alert show];
}
else
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"GameCenterUnAvailable" object:nil];
}
}
}

I want this button to show an error message if you are on iOS 5.1

I have a button that shares twitter message. The problem is social network does not work on iOS 5.1 so my question is how do I send an error message if the user is using iOS 5.1?
-(IBAction)Twitter:(id)sender{
if([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter]) {
SLComposeViewController *controller = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
SLComposeViewControllerCompletionHandler myBlock = ^(SLComposeViewControllerResult result){
if (result == SLComposeViewControllerResultCancelled) {
NSLog(#"Cancelled");
} else
{
NSLog(#"Done");
}
[controller dismissViewControllerAnimated:YES completion:Nil];
};
controller.completionHandler =myBlock;
[controller setInitialText:#"#VOX"];
[controller addURL:[NSURL URLWithString:#""]];
[controller addImage:[UIImage imageNamed:#""]];
[self presentViewController:controller animated:YES completion:Nil];
}
else{
alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Please check your Twitter settings." delegate:self cancelButtonTitle:#"cancel" otherButtonTitles:nil ,nil];
[alert show];
}
}
This is my code.
If you are supporting iOS 5.1 as your deployment target, not allowing the user to post their tweet is a terrible user experience. Instead, your method should look something like this:
- (IBAction)sendTweetTapped:(id)sender {
if ([SLComposeViewController class]) {
// Execute your code as you have it
}
else {
// Use TWTweetComposeViewController and the Twitter framework
}
}
You'll need to weakly link the Social framework. In doing so, if the user's iOS version doesn't support the Social framework (i.e. is less than 6.0), you're basically just sending a message to nil, which is allowed. In such a case, you'd fall back to using the Twitter framework and everyone gets to happily tweet!
** NOTE: I changed the name of your method because it's terrible and doesn't describe what-so-ever what the method is supposed to do.
To solely get the system version, you can find a good answer already here: How can we programmatically detect which iOS version is device running on?
To sum it up, however, you can call:
[[[UIDevice currentDevice] systemVersion] floatValue];
Which returns the iOS version as a float value.
This, however, is a bad practice for what you need it for. It is better to check for a feature as well as checking for the current OS.To fully successfully integrate Twitter you should consider including built in Twitter functionality for iOS 5.0 as well (You will need to weakly include and #import both Twitter.framework and Social.framework):
float osv = [[[UIDevice currentDevice] systemVersion] floatValue];
if (osv >= 6.0 && [SLComposeViewController class]) { //Supports SLComposeViewController, this is preferable.
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter]) {
//Success, you can tweet! (using the class SLComposeViewController)
} else {
if ([TWTweetComposeViewController canSendTweet]) { //Perhaps redundant, but worth a try maybe?
//Success, you can tweet! (using the class TWTweetComposeViewController)
} else {
//Error Message
}
}
} else if (osv < 6.0 && osv >= 5.0 && [TWTweetComposeViewController class]) {
if ([TWTweetComposeViewController canSendTweet]) {
//Success, you can tweet! (using the class TWTweetComposeViewController)
} else {
//Error Message
}
} else {
//No internal solution exists. You will have to go with 3rd party or write your own.
}

Get return values between these 2 classes

below is part of my code that I'm working on for quick reply on iOS 5, what i want to know is how to get the return values from the 3 methods under SBBulletinBannerItem to show up in the title and message fields accordingly, after i get this sorted out, I'm going to use the _appName return value to tell the gesture to open the quick reply alert if its sms, or to open the app if its anything else, I've tried quite a bit of things and can't seem to get it to work, thank you
%hook SBBulletinBannerController
- (void)_handleBannerTapGesture:(id)qreply
{
qreply = [[UIAlertView alloc] initWithTitle:#"title" message:#"message" delegate:self cancelButtonTitle:#"Close" otherButtonTitles:#"Reply", nil];
[qreply show];
[qreply release];
}
%end
%hook SBBulletinBannerItem
- (id)_appName { return %orig; }
- (id)title { return %orig; }
- (id)message { return %orig; }
%end

White blank screen after login in Facebook with FBConnect iphone

I am using FBConnect API...And I am using this code while pressing button..
- (IBAction)postGradesTapped:(id)sender {
_posting = YES;
// If we're not logged in, log in first...
if (![_session isConnected]) {
self.loginDialog = nil;
_loginDialog = [[FBLoginDialog alloc] init];
[_loginDialog show];
}
// If we have a session and a name, post to the wall!
else if (_facebookName != nil) {
[self postToWall];
}
// Otherwise, we don't have a name yet, just wait for that to come through.
}
Now when I press the button...
White blank screen Comes up...:(
What can be the problem??
As per your code, on login success you are posting on your wall. So it may be getting blank screen. Try print something on console on login success.