Question

I'm integrating my iOS app with Parse and Facebook. It works fine on my iPhone 4s - running iOS 6 -- but when I try a test account on my xCode 5 simulator it fails.

When I press my login with facebook button I'm presented with a screen saying: You have already authorized Test999 (my app's name.) This happens right when I'm calling this line:

[PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) 

I press OK. It sends me to a "You have to log in first" screen. I put in my username and password, and press Log In -- and I'm sent back to the You have already authorized Test999. I press OK -- and I'm presented with a blank view with an x on the top left to close it. There's nothing else to do so I push it, and I'm sent back to the "You have to log in first" screen.

So there's really no way to log in with the simulator. I tried to "Reset content and settings" but it doesn't help.

Following an answer on a similar problem I tried adding a reconnectWithFb method (below) and I also updated my Facebook sdk to version 3.9. Nothing helps.

This is from my login with facebook method:

[PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) {

if (!user) {
    if (!error) {
        NSLog(@"Uh oh. The user cancelled the Facebook login.");
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"User cancelled facebook login" message:@"Uh oh. The user cancelled the Facebook login." delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Dismiss", nil];
        [alert show];
    } else {
        NSLog(@"welcome screen loginWithFB: Uh oh. An error occurred: %@", error);
        [self performSelector:@selector(reconnectWithFB) withObject:nil afterDelay:0.5];
    }
} else if (user.isNew) {
    NSLog(@"New user with facebook signed up and logged in!");
} else {
    NSLog(@"User with facebook logged in!");        
    FBRequest *request = [FBRequest requestForMe];
    [request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
        if (!error) {
            NSString *facebookUsername = [result objectForKey:@"name"];
            [PFUser currentUser].username = facebookUsername;
            [[PFUser currentUser] setObject:[result objectForKey:@"id"] forKey:@"facebookid"];
            [[PFUser currentUser] saveEventually];
            [[NSNotificationCenter defaultCenter] postNotificationName:kUsersToWatchNotification object:result];
        } else {
            NSLog(@"Error getting the FB username %@", [error description]);
        }
    }];
}

and my reconnectWithFB (which on the simulator always have an empty fbAccounts array:)

-(void) reconnectWithFB {
    NSLog(@"reconnectWithFB called");
    ACAccountStore *accountStore;
    ACAccountType *accountTypeFB;
    if ((accountStore = [[ACAccountStore alloc] init]) && (accountTypeFB = [accountStore  accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook] ) ){
    NSArray *fbAccounts = [accountStore accountsWithAccountType:accountTypeFB];

    NSLog(@"fbAccounts %@", fbAccounts);

    id account;
    if (fbAccounts && [fbAccounts count] > 0 && (account = [fbAccounts objectAtIndex:0])){
        [accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {
                //we don't actually need to inspect renewResult or error.
                if (error){
                    NSLog(@"error in reconnectWithFB %@", error);
                }
        }];
      } 
   }
}

Any help with this would be greatly appreciated.

Was it helpful?

Solution

Looks like the solution was to add the open url methods to my App Delegate:

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    return [PFFacebookUtils handleOpenURL:url];
}

and

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url     sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    return [PFFacebookUtils handleOpenURL:url];
}

OTHER TIPS

Updated way:

In your AppDelegate.m put the following:

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
    return [FBAppCall handleOpenURL:url
                  sourceApplication:sourceApplication
                        withSession:[PFFacebookUtils session]];
}

Then make sure you call this:

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [FBAppCall handleDidBecomeActiveWithSession:[PFFacebookUtils session]];
        [FBAppEvents activateApp]; 
}

Later on in the coding make sure you add this one-liner:

- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    [[PFFacebookUtils session] close];
}

This Answer Seems to be OutDated, the Compiler Warns of Deprecation.

Current Method should be :

- (BOOL) handleOpenURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    return [FBAppCall handleOpenURL:url
                      sourceApplication:sourceApplication
                      withSession:[PFFacebookUtils session]];
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top