Facebook iOS SDK not calling completion handler when authorized app - ios

I call doFacebookLogin my app switches to facebook to authorize the app but after I allow the app to access my information and switches back.
Nothing happen. No "complete" in console.
If I call doFacebookLogin again the console shows
complete
Session state closed
Here is my code.
- (void)doFacebookLogin:(id)sender
{
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:YES
completionHandler:
^(FBSession *session,FBSessionState state, NSError *error) {
NSLog(#"complete");
[self sessionStateChanged:session state:state error:error];
}];
}
- (void)sessionStateChanged:(FBSession *)session state:(FBSessionState)state error:(NSError *)error
{
NSLog(#"Session state changed");
switch (state) {
case FBSessionStateOpen:
NSLog(#"Session state open");
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if(error == nil) {
NSLog(#"%#", [user debugDescription]);
}
}];
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
NSLog(#"Session state closed");
[FBSession.activeSession closeAndClearTokenInformation];
break;
default:
break;
}
if(error) {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}

Do you have this in AppDelegate?
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
// attempt to extract a token from the url
if ([[url scheme] hasPrefix:#"fb"]) {
return [FBSession.activeSession handleOpenURL:url];
}
.....
And also you need to check if your app has Url Types section for facebook in AppName-info.plist

Related

facebook sdk ios get user information

I'm using facebook sdk 3.0, however I'm facing difficulties when I'm trying to get user's information like email etc.
My Code:
- (IBAction)fbLogin:(id)sender {
[self facebookLogin];
}
-(void) facebookLogin
{
[FBSession openActiveSessionWithReadPermissions:#[#"email"]
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
switch (state) {
case FBSessionStateOpen:
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *FBuser, NSError *error) {
if (error) {
}
else {
name = [FBuser name];
email = [FBuser objectForKey:#"email"];
pic = [NSString stringWithFormat:#"https://graph.facebook.com/%#/picture?type=large", [FBuser objectID]];
}
}];
[self checkUser];
break;
}
}];
}
My code opens the Facebook login, and ask for authorisation but after that It returns to my app showing/geting nothing with that.
I diagnose through break points and found that after the line switch (state) it simply exits without giving any information.
My Question is, how can I fetch user's email via facebook sdk 3.0.
add the below to app delegate:
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
}
don't forget to import the header:
#import "FacebookSDK.h"

iOS Facebook get friends list

- (void)viewDidLoad
{
[super viewDidLoad];
m_allFriends = [[NSMutableArray alloc] init];
if ([[FBSession activeSession] isOpen])
{
if ([[[FBSession activeSession] permissions]indexOfObject:#"user_friends"] == NSNotFound)
{
[[FBSession activeSession] requestNewPublishPermissions:[NSArray arrayWithObject:#"user_friends"] defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session,NSError *error){
[self getFBFriendListFunc];
NSLog(#"1");
}];
}
else
{
[self getFBFriendListFunc];
NSLog(#"2");
}
}
else
{
[FBSession openActiveSessionWithPublishPermissions:[NSArray arrayWithObject:#"user_friends"]
defaultAudience:FBSessionDefaultAudienceOnlyMe
allowLoginUI:YES
completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
if (!error && status == FBSessionStateOpen) {
[self getFBFriendListFunc];
NSLog(#"3");
}else{
NSLog(#"error");
}
}];
}
}
-(void)getFBFriendListFunc
{
[FBRequestConnection startWithGraphPath:#"me/friends"
parameters:nil
HTTPMethod:#"GET"
completionHandler:^(
FBRequestConnection *connection,
id result,
NSError *error
) {
NSLog(#"me/friends result=%#",result);
NSLog(#"me/friends error = %#", error.description);
NSArray *friendList = [result objectForKey:#"data"];
[m_allFriends addObjectsFromArray: friendList];
}];
}
I try to connect Facebook with their API, actually this code connect Facebook, Facebook ask me this application want to use your information than i confirmed. Last step, Facebook return again my application than this getFBFriendListFunc should be run but none of if/else work. Nothing display...
I get this codes on Facebook developer which code part wrong ?
Any idea ?
Thank you...
For inviting users you can use the following code after adding the facebook-sdk
[FBWebDialogs
presentRequestsDialogModallyWithSession:sharedFacebookHelper.session
message:#"Your invite message"
title:nil
parameters:nil
handler:^(FBWebDialogResult result, NSURL *resultURL, NSError *error) {
if (error) {
// An error occurred, we need to handle the error
// See: https://developers.facebook.com/docs/ios/errors
NSLog(#"Error publishing story: %#", error.description);
} else {
if (result == FBWebDialogResultDialogNotCompleted) {
// User canceled.
NSLog(#"User cancelled.");
} else {
// Handle the publish feed callback
}
}
}];
I add this function on AppDelegate.m if this function does not exit login session never be work i hope this code help any one :)
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
BOOL wasHandled = [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
return wasHandled;
}

Facebook Session Closed

I'm implementing the Facebook Login in my iOS app. I think it is well implemented, however I have a problem. I run the login at the settings of the application. When I leave the app and then when I come back, if I want to use a Facebook action (i.e. share photos) I'm not able to do that because the session is closed. When I go to the settings menu where I've the login button, the session reopen without perform the login again (just direct me to the view where is the login button and the session is opened again).
So, I need the active session without the user having (always) to go to the settings menu. Any suggestions?
Thanks
I faced same problem :
had to make
#property (strong, nonatomic) FBSession *session;
in AppDelegate
in
(void)applicationDidBecomeActive:(UIApplication *)application {
[FBAppEvents activateApp];
[FBAppCall handleDidBecomeActiveWithSession:self.session]; }
in
(void)applicationWillTerminate:(UIApplication *)application { [self.session close]; }
in
(BOOL)application:(UIApplication *)application
openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
return [FBAppCall handleOpenURL:url
sourceApplication:sourceApplication
withSession:self.session]; }
in your settings class
if (appDelegate.session.isOpen)
{
[FBSession setActiveSession:appDelegate.session];
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection,
NSDictionary *user, NSError *error)
{
[self registerationWithFBRequestConnection:connection andFBGraphUser:user andNSError:error];
}];
}
else
{
[appDelegate.session closeAndClearTokenInformation];
NSArray *permissions = [NSArray arrayWithObjects:#"email", nil];
appDelegate.session = [[FBSession alloc] initWithPermissions:permissions];
[FBSession setActiveSession:appDelegate.session];
[appDelegate.session openWithBehavior:(FBSessionLoginBehaviorWithFallbackToWebView)
completionHandler:^(FBSession *session, FBSessionState status, NSError
*error)
{
[self sessionStateChangedWithFBSession:session andFBSessionState:status andNSError:error];
}];
}
(void)sessionStateChangedWithFBSession:(FBSession*)session andFBSessionState:(FBSessionState)status andNSError:(NSError*) error {
switch (status)
{
case FBSessionStateOpen:
{ [[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection,
NSDictionary *user, NSError *error)
{
[self registerationWithFBRequestConnection:connection andFBGraphUser:user andNSError:error];
}]; }
break;
case FBSessionStateClosed:
break;
case FBSessionStateClosedLoginFailed:
break;
default:
break;
} }
in your in registerationWithFBRequestConnection: methods you should handle it.. in Settings get all information about user.

Logout from facebook in iOS app

I am creating a simple iOS App that Login to facebook, Fetch self and friends details, Logout from facebook.
Now Login from Facebook and Fetching self & friends details is working ok, but I am not able to logout fully from facebook. Whenever I logout and then Login back - I see the Authorization screen instead of Authentication Login screen of Facebook (of Web).
Below is my code - can you please see if there is something wrong in the steps I have performed from Login, to Fetching self & friends details and Logging out from facebook
1) Login to Facebook using below method
- (void)openSession
{
if(FBSession.activeSession.isOpen)
{
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:NO
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error)
{
[self sessionStateChanged:session state:state error:error];
}];
}
else
{
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:YES
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error)
{
[self sessionStateChanged:session state:state error:error];
}];
}
}
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen:
{
// Connection is Open
lblStatus.text = #"FBSessionStateOpen";
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
{
[FBSession.activeSession closeAndClearTokenInformation];
// Connection is Closed / Login Failed
lblStatus.text = #"FBSessionStateClosed";
}
break;
default:
break;
}
}
2) Fetching self details and Friends details using below method
if (FBSession.activeSession.isOpen)
{
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection,
NSDictionary<FBGraphUser> *user,
NSError *error) {
if (!error) {
self.lblSelfDetails.text = user.name;
self.profilePicture.profileID = user.id;
}
}];
}
FBRequest *friendRequest = [FBRequest requestForGraphPath:#"me/friends?fields=name,birthday"];
[friendRequest startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error)
{
NSArray *data = [result objectForKey:#"data"];
for (FBGraphObject<FBGraphUser> *friend in data)
{
NSLog(#"%#:%#", [friend name],[friend birthday]);
}
}];
3) Logout using below method
- (IBAction)logout:(id)sender
{
[FBSession.activeSession closeAndClearTokenInformation];
}
Please use this method to logut successfully from the facebook
- (void)logout:(id<FBSessionDelegate>)delegate {
_sessionDelegate = delegate;
NSMutableDictionary * params = [[NSMutableDictionary alloc] init];
[self requestWithMethodName:#"auth.expireSession"
andParams:params andHttpMethod:#"GET"
andDelegate:nil];
[params release];
[_accessToken release];
_accessToken = nil;
[_expirationDate release];
_expirationDate = nil;
NSHTTPCookieStorage* cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray* facebookCookies = [cookies cookiesForURL:
[NSURL URLWithString:#"https://m.facebook.com"]];
for (NSHTTPCookie* cookie in facebookCookies) {
[cookies deleteCookie:cookie];
}
if ([self.sessionDelegate respondsToSelector:#selector(fbDidLogout)]) {
[_sessionDelegate fbDidLogout];
}
}
Hope this helps you!!!
Add this mathod in appdelegate.m
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
return [FBSession.activeSession handleOpenURL:url];
}
Then Add these methods in your .m file
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen: {
UIViewController *topViewController =
[self.navController topViewController];
if ([[topViewController modalViewController]
isKindOfClass:[SCLoginViewController class]]) {
[topViewController dismissModalViewControllerAnimated:YES];
}
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
// Once the user has logged in, we want them to
// be looking at the root view.
[self.navController popToRootViewControllerAnimated:NO];
[FBSession.activeSession closeAndClearTokenInformation];
[self showLoginView];
break;
default:
break;
}
if (error) {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
- (void)openSession
{
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:YES
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
Next, create a new method that will close the current session and log a person out:
-(void)logoutButtonWasPressed:(id)sender
{
[FBSession.activeSession closeAndClearTokenInformation];
}

Handle cancel button in facebook iOS using session

I tried to search this but couldn't find anything useful.
[FBSession setActiveSession:[[FBSession alloc] initWithPermissions:[NSArray arrayWithObjects:#"publish_actions,read_stream,user_hometown,user_birthday,email", nil]]];
[[FBSession activeSession] openWithBehavior:FBSessionLoginBehaviorForcingWebView completionHandler:
^(FBSession *session,FBSessionState state,NSError *error)
{
if(state == FBSessionStateOpen)
{
// use user's detail and post on Facebook
}
}];
Now this works fine for me. But what if user presses close/cancel button before logging into Facebook. I need to execute set of statements if user pressed cancel button. How can i do this.
Any help would be appreciated.
You can use Facebook error category and to handle errors refer this link
[FBSession openActiveSessionWithPublishPermissions:permissions defaultAudience:FBSessionDefaultAudienceEveryone allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState status, NSError* error){
if(!error){
//success do something
}
else{
//Error
if([FBErrorUtility errorCategoryForError:error] == FBErrorCategoryUserCancelled){
//user have pressed on cancel/close button
}
else {
//loging failed
}
}
}];
try this
[FBSession setActiveSession:[[FBSession alloc] initWithPermissions:[NSArray arrayWithObjects:#"publish_actions,read_stream,user_hometown,user_birthday,email", nil]]];
[[FBSession activeSession] openWithBehavior:FBSessionLoginBehaviorForcingWebView completionHandler:
^(FBSession *session,FBSessionState state,NSError *error)
{
if(state == FBSessionStateOpen)
{
// use user's detail and post on Facebook
}
else if(state == FBSessionStateClosed)
{
// if user not authenticated
}
else if(steate == FBSessionStateClosedLoginFailed)
{
}
}];
After calling the login function, eg:
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI {
NSArray *permissions = [NSArray arrayWithObjects:#"friends_photos",#"friends_birthday",#"email", nil];
return [FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
You can get the callback in the delegate meth9od , eg:
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState)state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen:
if(!error)
{
}
break;
case FBSessionStateClosed:
{
NSLog(#"FBSessionStateClosed");
[FBSession.activeSession closeAndClearTokenInformation];
}
break;
case FBSessionStateClosedLoginFailed:
{
NSLog(#"FBSessionStateClosedLoginFailed :- logged failed");
}
break;
default:
break;
}
[[NSNotificationCenter defaultCenter] postNotificationName:FBSessionStateChangedNotification
object:session];
if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:#"Error: %#",
[AppDelegate FBErrorCodeDescription:error.code]]
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}

Resources