iOS Facebook SDK delegate methods not called - ios

I see this question asked in several other posts but nothing seems to work for me. After following the FB login guide I had a working prototype that would allow users to authenticate with FB. However this guide instructs you place all FB OAuth logic directly into the AppDelegate and that is not ideal for me since I will support more than just FB authentication. So what I have done is move the login logic into it's own class. Since then it seems that the FB delegate methods do not get called after a user successfully authenticates with FB and control should be passed back to my application.
I have a modal login view which takes my FacebookAuth class as a delegate. When I attempt to create a session the FB login page appears and I authorize my application. After that no other delegate methods are called. Can anyone provide some hints?
#interface FacebookAuth()
#property (nonatomic, strong) User *sessionUser;
#end
#implementation FacebookAuth
#synthesize sessionIsOpen = _sessionIsOpen;
#synthesize sessionUser = _sessionUser;
-(id)initWithViewDelegate:(id<AuthorizationViewDelegate>)viewDelegate
{
NSAssert(viewDelegate != nil, #"FacebookAuth must be initialized with a view delegate.");
self = [super init];
if (self) {
self.viewDelegate = viewDelegate;
}
return self;
}
-(id)init
{
self = [super init];
if (self) {
self = [self initWithViewDelegate:nil];
}
return self;
}
-(BOOL)sessionIsOpen{
return (FBSession.activeSession.state == FBSessionStateOpen);
}
-(void)requestSessionUserWithSuccess:(void (^)(User *))success Failure:(void (^)(NSError *))error{
if(!self.sessionIsOpen){
error([NSError errorWithDomain:#"Session Closed" code:0 userInfo:nil]);
return;
}
if(self.sessionUser == nil){
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection,
NSDictionary<FBGraphUser> *user,
NSError *err) {
if (!err) {
User *ses_user = [[User alloc]initWithId:user.id first:user.first_name last:user.last_name sessionToken: [[[FBSession activeSession] accessTokenData] accessToken]];
self.sessionUser = ses_user;
success(ses_user);
} else{
error(err);
}
}];
} else{
success(self.sessionUser);
}
}
-(void)openSession
{
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:YES
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
}
-(void)closeSession{
[FBSession.activeSession closeAndClearTokenInformation];
self.sessionUser = nil;
self.sessionIsOpen = NO;
};
-(void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen:{
self.sessionIsOpen = YES;
[self.viewDelegate loginSuccess];
}
break;
case FBSessionStateClosed:{
self.sessionIsOpen = NO;
}
break;
case FBSessionStateClosedLoginFailed:{
[FBSession.activeSession closeAndClearTokenInformation];
self.sessionIsOpen = NO;
[self.viewDelegate loginFailure:error];
}
break;
default:
break;
}
}
-(BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
return [FBSession.activeSession handleOpenURL:url];
}
I apologize for the large code snippet but I don't want to leave out anything that may be valuable in assisting.
After calling
-(void)openSession:
The facebook authentication page appears and I authorize the application. After that I was expecting the FB delegate method to be called:
-(BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
It never is. Do I need to declare this class as a type of FB delegate? I am using the latest Facebook SDK available.
Any help would be great.

Related

FBSession Completion Handler not working and open url not called?

appdelegate.m
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
// Yes, so just open the session (this won't display any UX).
NSLog(#"token loaded");
[self openSession];
} else {
// No, display the login page.
//[self showLoginView];
NSLog(#"token not loaded");
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
// We need to properly handle activation of the application with regards to Facebook Login
// (e.g., returning from iOS 6.0 Login Dialog or from fast app switching).
[FBSession.activeSession handleDidBecomeActive];
}
pragma mark -
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen: {
NSLog(#"session state open");
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
[FBSession.activeSession closeAndClearTokenInformation];
NSLog(#"session state closed");
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:#[#"public_profile, email, user_friends"] allowLoginUI:YES completionHandler:^(FBSession *session,
FBSessionState state, NSError *error) {
NSLog(#"It is never called");
[self sessionStateChanged:session state:state error:error];
}];
}
- (void)obatinUserInfo {
}
pragma mark -
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
NSLog(#"it is never called");
return [FBSession.activeSession handleOpenURL:url];
}
view controller.m
===========
button action
- (IBAction)performLogin:(id)sender {
AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate openSession];
}
This is my code when call Facebook login goes to opensession, but not called within completion handler and open url.
Many links i refered but not working.
The same code working indivitual project but integrated into my project means not working.
Please assist me
Thanks in advance
S.Arul

Not getting call to loginViewShowingLoggedInUser from FBLoginView

I am using the Facebook SDK for the first time. I am working with Xcode 5.1 and iOS 7.
I programmatically display FBLoginView:
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"viewDidLoad");
// Do any additional setup after loading the view.
if ( !loginView ) {
// loginView =[[FBLoginView alloc] initWithReadPermissions:#[#"basic_info"]];
loginView =[[FBLoginView alloc] initWithReadPermissions:[NSArray arrayWithObjects:#"basic_info", #"user_location", nil]];
}
loginView.delegate = self;
loginView.frame = CGRectOffset(loginView.frame,
(self.view.center.x -(loginView.frame.size.width /2)), 5);
CGPoint vCenter = CGPointMake( CGRectGetMidX(self.view.frame),
CGRectGetMidY(self.view.frame) );
CGPoint lvCenter = CGPointMake( vCenter.x, vCenter.y+100.0 );
loginView.center = lvCenter;
[self.view addSubview:loginView];
[self updateView];
}
I have implemented the required override functions:
#pragma mark - FBLoginViewDelegate
- (void) loginViewFetchedUserInfo:(FBLoginView *)loginView user:(id<FBGraphUser>)user {
NSLog(#"loginViewFetchedUserInfo");
[self updateView];
}
- (void) loginViewShowingLoggedInUser:(FBLoginView *)loginView {
NSLog(#"loginViewShowingLoggedInUser");
[self updateView];
}
- (void) loginViewShowingLoggedOutUser:(FBLoginView *)loginView {
NSLog(#"loginViewShowingLoggedOutUser");
[self updateView];
}
- (void)updateView {
NSLog(#"FB updateView");
[[FBRequest requestForMe] startWithCompletionHandler:
^(FBRequestConnection *connection, NSDictionary<FBGraphUser>*FBUser, NSError *error) {
if (error) {
NSLog(#"updateView - error");
} else {
NSLog(#"updateView - good");
NSNumber *owner_id = [NSNumber numberWithLong:[[FBUser id] longLongValue]];
if ( FB_user_id == nil ) {
FB_user_id = owner_id;
NSLog(#"FBUser ID = %#", FB_user_id);
loggedInSession = [FBSession activeSession];
[[NSUserDefaults standardUserDefaults] setObject:[FBUser id] forKey:#"eventOwnerID"];
[self performSegueWithIdentifier:#"continue_to_app" sender:self];
}
}
}];
if ([self checkFacebookSession]) {
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.view setNeedsDisplay];
});
}
The FBLoginView button appears with "Log in with Facebook". I can log in and accept permissions, but the loginViewShowingLoggedInUser override function never gets called.
Someone suggested adding the following:
- (BOOL) application:(UIApplication *) application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
NSLog ( #"application openURL");
NSLog ( #"URL = %#", url);
NSLog ( #"Application = %#", sourceApplication);
// Call FBAppCall's ha
BOOL wasHandled = [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
//[LoginUIViewController updateView];
return wasHandled;
}
This code had no effect and was never executed.
What am I doing wrong?
You are using #"basic_info", for this Facebook shows following error when I tried testing your code!
Invalid Scope: basic_info. Use public_profile, user_friends instead
I was interested in knowing where did you add the method:
- (BOOL) application:(UIApplication *) application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
NSLog ( #"application openURL");
NSLog ( #"URL = %#", url);
NSLog ( #"Application = %#", sourceApplication);
// Call FBAppCall's ha
BOOL wasHandled = [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
//[LoginUIViewController updateView];
return wasHandled;
}
It should be in your AppDelegate, which works for me.
The read permissions have changed.
Refer this :
[https://developers.facebook.com/docs/apps/changelog#v2_0_permissions
][1]
The Error "invalide scope : basic info use public_profile, user friends instead" clearly states that "basic_info" is invalid and it suggests to make use of "public_profile" or "user_friends" as the new scope.
Change it in the following code:
self.loginView.readPermissions = #[#"basic_info"];
TO
self.loginView.readPermissions = #[#"public_profile"];

Still need an answer. Calling popToRootViewController after FBSession is open

I STILL NEED AN ANSWER
I have the view controller where facebook login button was added. I have class: FacebookAuth with method:
- (void) performAuth {
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:YES
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error) {
[self fbSessionStateChanged:session state:state error:error];
}];
}
In my facebook view controller I have the IBAction:
- (IBAction)performFBLogin:(id)sender {
FacebookAuth *fbAuth = [[FacebookAuth alloc] init];
[fbAuth performAuth];
[self.navigationController popToRootViewControllerAnimated:YES];
}
The question is: how to call [self.navigationController popToRootViewControllerAnimated:YES]; after performAuth is performed.
According to the official guide there is a callback in the AppDelegate:
// During the Facebook login flow, your app passes control to the Facebook iOS app or Facebook in a mobile browser.
// After authentication, your app will be called back with the session information.
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
return [FBAppCall handleOpenURL:url sourceApplication:sourceApplication];
}
Thanks in advance.
i'm note sure but Have you try this way,
- (void) performAuth {
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:YES
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error) {
[self fbSessionStateChanged:session state:state error:error];
[self.navigationController popToRootViewControllerAnimated:YES];
}];
}

iOS Facebook login doesn't work

I have an app, for iOS5 and above, in which I am trying to set up Facebook login. All works fine when there is a Facebook account integrated in the phone. If it is not, it doesn't work. This is even if the Facebook app is installed.
When the app is installed, it opens the app, asks me permission to access the appropriate user data and returns to my app with no result. It the same when it isn't installed. Safari is opened, asks me for authorization, returns, and nothing.
I followed all the steps mentioned in the Facebook Login tutorial. Is this a problem only I am facing?
EDIT: This is the requested code:
I open a session like so:
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI {
NSArray *permissions = [[NSArray alloc] initWithObjects:
#"email",
nil];
return [FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
[self sessionStateChanged:session
state:state
error:error];
}];
}
And when it returns, I guess this method must be called. but it isn't:
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen:
if (!error) {
// We have a valid session
NSLog(#"session opened");
FBRequest *me = [FBRequest requestForMe];
__block NSString *username = nil;
[me startWithCompletionHandler:^(FBRequestConnection *connection,
id result,
NSError *error) {
NSDictionary<FBGraphUser> *my = (NSDictionary<FBGraphUser> *) result;
// NSLog(#"User session found: %#", my.username);
username = my.username;
}];
// /fb_access/:access_token
}
break;
case FBSessionStateClosed:
if (!error) {
// We have a valid session
NSLog(#"User session closed");
}
case FBSessionStateClosedLoginFailed:
NSLog(#"login failed, %#", error);
[FBSession.activeSession closeAndClearTokenInformation];
break;
default:
break;
}
[[NSNotificationCenter defaultCenter]
postNotificationName:FBSessionStateChangedNotification
object:session];
if (error) {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
Any ideas?
add below key-value pair in your plist.
Add Field (key) FacebookAppID - (value) fbID
Add Field - URL Types (key)
Add 2 Field in URL Types:
(key) URL Identifier - (value) (i.e. YourApplication name)
(key)-URL Schemes
Add Field in URL Schemes (key) - (value) fb(fbID) (e.g. fb557354324264278)
Add following method in to your appdelgate
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{ // attempt to extract a token from the url return
[FBSession.activeSession handleOpenURL:url];
}
Both answers by iUser and Kalpesh are right. Combining both of them worked for me. Please refer to them. :)

Facebook log in error 400

I am logging in into facebook in this way:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FBSession openActiveSessionWithReadPermissions:nil
allowLoginUI:YES
completionHandler:
^(FBSession *session,
FBSessionState state, NSError *error) {
[self sessionStateChanged:session state:state error:error];
}];
return YES;
}
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen:
if (!error) {
// We have a valid session
//NSLog(#"User session found");
// Initiate a Facebook instance
self.facebook = [[Facebook alloc]
initWithAppId:FBSession.activeSession.appID
andDelegate:nil];
// Store the Facebook session information
self.facebook.accessToken = FBSession.activeSession.accessToken;
self.facebook.expirationDate = FBSession.activeSession.expirationDate;
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
[FBSession.activeSession closeAndClearTokenInformation];
// Clear out the Facebook instance
self.facebook = nil;
break;
default:
break;
}
if (error) {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:#"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
// attempt to extract a token from the url
self.openedURL = url;
// attempt to extract a token from the url
return [FBSession.activeSession handleOpenURL:url];
}
...and I get the error: Error: HTTP status code: 400
I have set up the URL scheme in the plist. Why am I getting this?
Check in the App Dashboard. Look at your Basic Settings. Your Sandbox Mode may be set to Enabled. The errors should go away when your app is out of Sandbox mode.

Resources