FBSDKLoginManager logInWithPublishPermissions总是返回isCancelled = YES

我无法弄清楚如何将用户login到我的应用程序。 [FBSDKAccessToken currentAccessToken]是零,所以我打电话:

 [[[FBSDKLoginManager alloc] init] logInWithPublishPermissions:@[@"publish_actions"] handler:…]; 

根据所包含的示例项目。 这切换到Facebook应用程序,但消息说:“您已经授权应用程序名称 ”。 我点击确定,然后回到应用程序,但grantedPermissions和被declinedPermissions grantedPermissionsnil ,结果是isCancelledYES[FBSDKAccessToken currentAccessToken]仍然是nil

我无法弄清楚我应该如何获得currentAccessToken来填充。在我看来,调用logInWithPublishPermissions应该这样做,但事实并非如此。

你应该尝试添加你的AppDelegate didFinishLaunchingWithOptions:

 return [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions]; 

当用户login时,这会得到u [FBSDKAccessToken currentAccessToken]

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

如果此方法不在AppDelegate中,则会导致取消状态。

请参阅: https : //developers.facebook.com/docs/ios/getting-started#startcoding

当您的Facebook应用程序没有“publish_actions”权限,或者您没有使用testing用户时,可能会发生这种情况。

在Facebook上,去pipe理你的应用程序,然后确保你使用的Facebook用户是作为pipe理员或testing人员在“angular色”下定义的。

如果它不是testing用户或pipe理员 – Facebook会要求“publish_actions”权限在允许您的应用程序使用之前进行审查和批准,否则您将收到“isCancelled = YES”的结果。

在使用此权限testing您的应用程序之后,可以提交此权限以进行审查,您需要上传一个演示如何使用此权限的二进制文件,以及如何使用此权限的详细信息。 获得批准后,您可以将其用于未经testing的Facebook用户。

由于FBSDKLoginKit 4.6.0, logInWithReadPermissionslogInWithPublishPermissions方法似乎有附加的fromViewController参数,并使用它来呈现模态。

我在logInWithPublishPermissions的callback里面调用了logInWithReadPermissions ,在那个时候模态还没有完全解决 。 (我知道在不需要的时候询问权限是个不好的习惯,但在我的情况下,这似乎是正确的地方。)这导致它失败, isCancelled等于YES。 我添加了一些延迟,等待模式被完全解散,解决了这个问题。

当我在这里登陆时遇到了同样的问题,事实certificate我只是使用了不推荐的应用程序openURL方法,因为我也使用了谷歌login。 要支持iOS 8,并且必须实现当前和不推荐使用的方法:

 func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { return GIDSignIn.sharedInstance().handle(url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String!, annotation: options[UIApplicationOpenURLOptionsKey.annotation]) || FBSDKApplicationDelegate.sharedInstance().application(app, open: url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String, annotation: options[UIApplicationOpenURLOptionsKey.annotation]) } func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool { return GIDSignIn.sharedInstance().handle(url, sourceApplication: sourceApplication, annotation: annotation) || FBSDKApplicationDelegate.sharedInstance().application(application, open: url, sourceApplication: sourceApplication, annotation: annotation) } 

弃用的是第二个。

注意:FBSDK方法是在google之后添加一个“||” 操作员,但顺序并不重要,如果你只想使用Facebook方法只是删除方法和或运营商。

注2:由于swift 3仍然稳定的方法名称可以改变我build议你在覆盖和实现一个委托的方法时总是使用从XCode自动完成。

希望这有助于o /

此方法适用于iOS 9

 // Facebook Login Completion delegate - (void)loginButton:(FBSDKLoginButton *)loginButton didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error { if (result){ NSLog(@"%@",result); NSLog(@"%@",result.grantedPermissions); [self getFacebookData:result]; } } - (void)getFacebookData:(FBSDKLoginManagerLoginResult *)result{ if (![result.grantedPermissions containsObject:@"email"]) { FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init]; login.loginBehavior = FBSDKLoginBehaviorWeb; [login logInWithReadPermissions:@[@"email"] fromViewController:self handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { if (error) { // Process error } else if (result.isCancelled) { // Handle cancellations } else { if ([result.grantedPermissions containsObject:@"email"]) { NSLog(@"result is:%@",result); if ([FBSDKAccessToken currentAccessToken]) { [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields": @"first_name, last_name, email, id"}] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (!error) { NSLog(@"fetched user:%@", result); [self registerWithFacebook:result]; }else{ NSLog(@"%@",error); } }]; } } } }]; }else{ if ([FBSDKAccessToken currentAccessToken]) { [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields": @"first_name, last_name, email, id"}] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (!error) { NSLog(@"fetched user:%@", result); [self registerWithFacebook:result]; }else{ NSLog(@"%@",error); } }]; } } 

}

注意 :使用FBSDKLoginBehaviorWeb而不是FBSDKLoginBehaviorBrowser 。 这一定会奏效

另外,请确保您没有在您的didFinishLaunchingWithOptions方法中调用FBSDKAccessToken.currentAccessTokendidFinishLaunchingWithOptions的设置需要完成,因此令牌可以在尝试loginFacebook之前进行初始化。

FBSDKLoginManagerLoginResult.isCancelled意外YES

如果用户明确点击login对话框中的取消button,或者手动应用程序切换回您的应用程序(称为隐式取消),SDK将报告取消。 你应该确保你没有启动一个loginstream作为你的应用程序delegate的生命周期的一部分(例如在application:openURL:sourceApplication:annotation:启动一个loginapplication:openURL:sourceApplication:annotation:因为这将模仿一个隐式的取消。 如果必须,稍后将login启动分派给主队列,以便应用程序委托的生命周期首先完成。

我也面临同样的问题,我花了近2个小时来解决这个问题。 我做的是

 FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init]; **[login logOut];** // adding this single line fixed my issue [login logInWithReadPermissions: @[@"public_profile"] fromViewController:self handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { if (error) { NSLog(@"Process error"); } else if (result.isCancelled) { NSLog(@"Cancelled"); } else { NSLog(@"Logged in"); [self GetData]; } }] // I called this logout function 

问题解决了

我使用谷歌和Facebooklogin,所以我不得不实施我的openURL方法,像这样,iOS 9 +

 - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options { if ([[url absoluteString] containsString:@"YOURFBID"]) { return [[FBSDKApplicationDelegate sharedInstance] application:app openURL:url options:options]; } else { return [[GIDSignIn sharedInstance] handleURL:url sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]; } return NO; } 

//您可以使用访问令牌进一步执行任何操作

 - (void)GetData { if ([FBSDKAccessToken currentAccessToken]) { NSDictionary *AccessToken = [FBSDKAccessToken currentAccessToken]; [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields": @"id, name, first_name, picture.type(large) ,last_name"}] startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) { if (!error) { //NSLog(@"fetched user:%@", result); //NSDictionary *Result = result; NSDictionary *params = [NSMutableDictionary dictionaryWithObject:[AccessToken tokenString] forKey:@"access_token"]; } else { [self showAlertController:@"Error" message:error.localizedDescription]; } }]; } } 
 (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options { return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url options:options]; } // **Still need this for iOS8** - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(nonnull id)annotation { return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url sourceApplication:sourceApplication annotation:annotation]; } 

称这个方法,

 FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init]; [loginManager logInWithReadPermissions:@[@"user_friends"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { code }];