I am trying to implement Facebook login into my app. I already do everything that Facebook developer page recommends me but I can't do this work correctly.
I have already put my bundle identifier in Facebook Dev App
Facebook Config:
Xcode Project Config:
In my AppDelegate I put the code that Facebook indicates
#import <FBSDKCoreKit/FBSDKCoreKit.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
return YES;
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
BOOL handled = [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication: sourceApplication
annotation: annotation
];
return handled;
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[FBSDKAppEvents activateApp];
}
Also put the login button as shown in Facebook documentation
-(void) viewDidLoad() {
self.loginButton = [[FBSDKLoginButton alloc] init];
self.loginButton.readPermissions = @[@"public_profile", @"email", @"user_friends"];
[self.loginButton addTarget:self action:@selector(buttonFacebookLoginClicked:) forControlEvents:UIControlEventTouchUpInside];
self.manager =[[FBSDKLoginManager alloc] init];
}
But in the method buttonFacebookLoginClicked when I handle the response I always have result.isCancelled as true.
In the app when I click on FB login button I am redirected to a new tab in safari that does not show anything and then when I click on OK button the result is cancelled.
My Facebook login button:
Safari view:
There is my login function, and I always drop in the case that result.isCancelled is true, after click the OK button in Safari
- (IBAction)buttonFacebookLoginClicked:(id)sender {
if ([FBSDKAccessToken currentAccessToken] != nil) {
[self.manager logOut];
//return
}
[self.manager logInWithReadPermissions: self.loginButton.readPermissions fromViewController: self handler: ^(FBSDKLoginManagerLoginResult* result, NSError* error ) {
if (error != nil) {
//According to Facebook:
//Errors will rarely occur in the typical login flow because the login dialog
//presented by Facebook via single sign on will guide the users to resolve any errors.
// Process error
[self.manager logOut];
} else if (result.isCancelled) {
// Handle cancellations
for (NSString * p in self.loginButton.readPermissions) {
NSLog(@"PERMISSION %@", p);
}
[self.manager logOut];
} else {
// If you ask for multiple permissions at once, you
// should check if specific permissions missing
BOOL allPermsGranted = true;
//result.grantedPermissions returns an array of _NSCFString pointers
NSArray *grantedPermissions = [[result grantedPermissions] allObjects];
// let grantedPermissions = result.grantedPermissions.allObjects.map( {"\($0)"} )
for (NSString *permission in self.loginButton.readPermissions) {
for (NSString* grantedPerm in grantedPermissions) {
NSRange range = [permission rangeOfString:grantedPerm];
if (range.length == 0) {
allPermsGranted = false;
break;
}
}
}
if (allPermsGranted) {
// Do work
NSString * fbToken = [[result token] tokenString];
NSString * fbUserID = [[result token] userID];
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
initWithGraphPath:@"/me"
parameters:@{@"fields": @"id,name,email"}
HTTPMethod:@"GET"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
NSLog(@"result %@", result);
NSDictionary *dict = @{
@"email" : @"email" ,
@"providerID" : @"id",
@"username" : @"name",
@"provider" : @"facebook"
};
NSLog(@"DICT %@", dict);
[self.delegate loginWithCredentials:dict];
[self logUserLoggedInWithFacebookEvent];
}];
} else {
//The user did not grant all permissions requested
//Discover which permissions are granted
//and if you can live without the declined ones
NSLog(@"FACEBOOK LOGIN ERROR");
}
}
}];
}
I think that is a less error but I can't find it.




