Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Facebook SDK iOS login with Facebook app installed

UPDATE: I've realized that the below problem only occurs if the user has already given Facebook access to my app, and then reinstals my app. The first time the user selects the Facebook button in my app, it goes to the Facebook app to get authentication, but since the authentication status is still saved in the Facebook app, it returns immediately to my app without explanation to the user, and the postToFacebookWall method fails.

UPDATE 2: I ended up implementing the solution found here: How to authorize user through a DIALOG with the NEW Facebook Connect iOS API? and avoided the Facebook app. Safari is better because at least the user gets a message saying that they will be logging in. However the Feed Dialogue still fails the first time as before.


I'm having what must be a common problem, but I haven't been able to find the solution yet. Note that my app is restricted to iOS 5 and above.

I have an app with a Facebook button for posting to a users wall. When the button is pressed, the app will check to see if the user has already given permission to the app to post to the wall. If they have, a view pops up with a Feed Dialog with the wall post information. If they haven't, Safari will be opened and the user will be allowed to login. After logging in they will be taken back to the app and the Feed Dialog view will pop up.

This works on the Simulator, and on my device, if the Facebook app is not installed. If the Facebook app is installed, the user is taken to the Facebook app, but then immediately returned to the original app, without allowing the user to do anything. The Feed Dialog pops up, but it is completely blank and dismisses automatically. Pressing the Facebook button again will bring up the Feed Dialog view as it is supposed to once the user has given permission to the app to post to their wall.

I pretty much followed the instructions found here: http://developers.facebook.com/docs/mobile/ios/build/#implementsso

and here: http://developers.facebook.com/docs/reference/dialogs/feed/

In the AppDelegate I have the following code:

- (void)loginToFacebook
{
    // Set up facebook
    self.facebook = [[Facebook alloc] initWithAppId:@"YOUR_APP_ID" andDelegate:self];

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    if ([defaults objectForKey:@"FBAccessTokenKey"] 
        && [defaults objectForKey:@"FBExpirationDateKey"]) {
        self.facebook.accessToken = [defaults objectForKey:@"FBAccessTokenKey"];
        self.facebook.expirationDate = [defaults objectForKey:@"FBExpirationDateKey"];
    }

    if (![self.facebook isSessionValid]) {
        [self.facebook authorize:nil];
    }
}

// This is an FBSessionDelegate protocol method
// that gets called after a successful login
- (void)fbDidLogin 
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:[self.facebook accessToken] forKey:@"FBAccessTokenKey"];
    [defaults setObject:[self.facebook expirationDate] forKey:@"FBExpirationDateKey"];
    [defaults synchronize];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"POST_TO_FACEBOOK_WALL" object:nil];
}

// This is a UIApplicationDelegate protocol method
// It is called when safari is dismissed
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication annotation:(id)annotation 
{
    return [self.facebook handleOpenURL:url]; 
}

The only difference between this and the sample code is that I added an NSNotification that is picked up by my view controller, where I have the following code:

    - (void)facebookButtonPressed:(UIControl*)sender 
    {
        Facebook *facebook = [(AppDelegate*)[[UIApplication sharedApplication] delegate] facebook];

        if (![facebook isSessionValid])
        {
            // Login to facebook if not already logged in
            [(AppDelegate*)[[UIApplication sharedApplication] delegate] loginToFacebook];
        }
        else 
        {
            [self postToFacebookWall];
        }

    }

    - (void)postToFacebookWall
    {
        Facebook *facebook = [(AppDelegate*)[[UIApplication sharedApplication] delegate] facebook];

        /*Facebook Application ID*/
        // TODO: Get this either from the AppDelegate facebook property or the info plist
        NSString *client_id = @"YOUR_APP_ID";

        NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
  kAppId, @"app_id",
  @"http://developers.facebook.com/docs/reference/dialogs/", @"link",
  @"http://fbrell.com/f8.jpg", @"picture",
  @"Facebook Dialogs", @"name",
  @"Reference Documentation", @"caption",
  @"Using Dialogs to interact with users.", @"description",
  nil];

        [facebook dialog:@"feed" andParams:params andDelegate:self];
    }

Does anyone know how to fix my issue? (Also, in case it isn't clear, YOUR_APP_ID is replaced with my app id in my code).

like image 865
Darren Avatar asked Mar 19 '12 20:03

Darren


People also ask

What is Facebook SDK for iOS?

The Facebook SDK enables: Facebook Login - Authenticate people with their Facebook credentials. Share and Send dialogs - Enable sharing content from your app to Facebook. App Events - Log events in your application.

How do I know if Facebook SDK is installed?

First, go to your Analytics for Apps page: Analytics for Apps. Then, click "Mobile App Installs” from the left-hand navigation, and check your last install reported to confirm proper installation of the SDK.


2 Answers

This sounds like an out-case in that it is this scenario of 'only when the app was installed, authed, then uninstalled, then reinstalled'.

You should be able to fall-back to "classic web view authentication" when this particular thing happens.

if (facebookAppDidNotReturnProperly) {
   // therefore I must have been re-installed 
   // fallback to UIWebView

   [facebook authorizeWithFBAppAuth:NO safariAuth:NO];
}

Then again, you could also use safari auth too I suppose.

like image 87
slf Avatar answered Oct 19 '22 14:10

slf


I ended up solving my questions by implementing the two solutions found here:

https://stackoverflow.com/a/5683454/472344

https://stackoverflow.com/a/9137887/472344

like image 40
Darren Avatar answered Oct 19 '22 15:10

Darren