ios FBSDKLoginManager logInWithPublishPermissions 总是返回 isCancelled=YES

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29358661/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 05:25:39  来源:igfitidea点击:

FBSDKLoginManager logInWithPublishPermissions always returns isCancelled=YES

iosfacebookfacebook-ios-sdk

提问by devios1

I am having trouble figuring out how to log a user into my app. [FBSDKAccessToken currentAccessToken]is nil, so I am calling:

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

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

as per the included sample project. This switches to the Facebook app, but the message says "You have already authorized App Name.". I click OK and it goes back into the app, but grantedPermissionsand declinedPermissionsare both nilon the result, and isCancelledis YES. [FBSDKAccessToken currentAccessToken]is still nil.

根据包含的示例项目。这会切换到 Facebook 应用程序,但消息显示“您已经授权App Name.”。我点击确定并退回到应用程序,但grantedPermissionsdeclinedPermissionsnil对结果,以及isCancelledYES[FBSDKAccessToken currentAccessToken]还在nil

I can't figure out how I'm supposed to get currentAccessTokento be filled in. It seems to me the call to logInWithPublishPermissionsshould do that, but it isn't.

我不知道我应该如何currentAccessToken被填补。在我看来logInWithPublishPermissions应该这样做,但事实并非如此。

回答by Dheeraj Singh

You should try adding in your AppDelegate didFinishLaunchingWithOptions :

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

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

This would get u [FBSDKAccessToken currentAccessToken]when user is logged in.

[FBSDKAccessToken currentAccessToken]当用户登录时,这会得到你。

and

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

If this method is not present into AppDelegate then it results into cancelled state.

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

Refer to : https://developers.facebook.com/docs/ios/getting-started#startcoding

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

回答by Kof

This can happen when your Facebook App doesn't have "publish_actions" permission, or you're not using a test user.

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

On Facebook, go to manage your app, then make sure that the Facebook user you're using is defined under "Roles" as an admin or tester.

在 Facebook 上,转到管理您的应用程序,然后确保您使用的 Facebook 用户在“角色”下定义为管理员或测试员。

If it's not a test user or admin - Facebook will require "publish_actions" permission to be reviewed and approved before allowing your app to use it, until then you'll receive a "isCancelled=YES" result.

如果它不是测试用户或管理员 - Facebook 将需要“publish_actions”权限才能允许您的应用使用它之前进行和批准,在此之前您将收到“isCancelled=YES”结果。

After testing your app with this permission, it is possible to submit this permission for review, you'll need to upload a binary that demonstrates usage of this permission with exact details on how to use it. After it's approved, you'll be able to use it with non-test Facebook users.

在使用此权限测试您的应用程序后,可以提交此权限以供审核,您需要上传一个二进制文件,演示此权限的用法以及如何使用它的确切详细信息。获得批准后,您就可以与非测试 Facebook 用户一起使用它。

回答by Lucas Martins Juviniano

I had the same problem when I landed here, turns out I was only using the deprecated application openURL method because i was using google sign in too. To support iOS 8 and before you have to implement both the current and the deprecated method:

我到达这里时遇到了同样的问题,结果我只使用了已弃用的应用程序 openURL 方法,因为我也在使用谷歌登录。要支持 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)
}

The deprecated is the second.

弃用的是第二个。

Note: The FBSDK method is added after the google one with an or "||" operator but the order doesn't matter and if you wanna only use facebook method just erase the method and the or operator.

注意:FBSDK 方法是在google 后面加上一个或“||” 运算符,但顺序无关紧要,如果您只想使用 facebook 方法,只需擦除方法和 or 运算符。

Note 2: As swift 3 still stabilizing the method name can change I suggest you always use the auto complete from XCode when overriding and implementing a delegate's method.

注意 2:由于 swift 3 仍然稳定方法名称可以更改,我建议您在覆盖和实现委托方法时始终使用 XCode 中的自动完成。

Hope this Helps o/

希望这有助于 o/

回答by Hlung

Since FBSDKLoginKit 4.6.0, the logInWithReadPermissionsand logInWithPublishPermissionsmethods of FBSDKLoginManager seems to have additional fromViewControllerargument and use that to present modals.

从 FBSDKLoginKit 4.6.0 开始, FBSDKLoginManager 的logInWithReadPermissionslogInWithPublishPermissions方法似乎有额外的fromViewController参数并使用它来呈现模态。

I was calling logInWithPublishPermissionsinside the callback of logInWithReadPermissions, which at that point the modal is not fully dismissed yet. (I know it's a bad practice to ask permission when it's not needed, but in my case this seems to be the right place to do.) This cause it to fail with isCancelledequals to YES. I added some delay and wait for the modal to be fully dismissed fixed the problem.

logInWithPublishPermissions在 的回调中调用logInWithReadPermissions,此时模态还没有完全解除。(我知道在不需要时请求许可是一种不好的做法,但在我的情况下,这似乎是正确的做法。)这导致它失败,isCancelled等于 YES。我添加了一些延迟并等待模态完全关闭解决了问题。

回答by jaya raj

This method works in iOS 9

此方法适用于 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);
             }
         }];
    }
}

}

}

NOTE: Use FBSDKLoginBehaviorWebinstead of FBSDKLoginBehaviorBrowser. This will surely work

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

回答by Salman Ghumsani

FBSDKLoginManagerLoginResult.isCancelledis unexpectedly YES:

FBSDKLoginManagerLoginResult.isCancelled出乎意料的是YES

The SDK will report a cancellation if the user explicitly taps a cancel button in the login dialogs, or if they manually app switch back to your app (known as an implicit cancellation). You should make sure you are not initiating a login flow as part of your app delegate's lifecycle (such as starting a login inside application:openURL:sourceApplication:annotation:) as that will mimic an implicit cancellation. If you must, dispatch the login initiation later to the main queue so that the app delegate's lifecycle completes first.

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

回答by Adeel Ahmed

I also faced the same issue and i spent almost 2 hours to resolve the issue. What i did is

我也遇到了同样的问题,我花了将近 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 

and the issue was fixed

问题已解决

i was using both google and Facebook login so i had to implement my openURL method like this, iOS 9+

我同时使用 google 和 Facebook 登录,所以我必须像这样实现我的 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;
}

// you can perform further any operations using the access token

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

- (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];
             }
         }];
    } }

回答by Cong Wang

(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];
}

回答by Yong Piao

1.check already added

1.check已添加

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

2.check already added

2.检查已经添加

- (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];
}

3. write this statement [FBSDKProfile enableUpdatesOnAccessTokenChange:YES];before

3.写这个声明[FBSDKProfile enableUpdatesOnAccessTokenChange:YES];之前

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

4.call logInWithReadPermissions method in dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{}

4.在dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{}中调用logInWithReadPermissions方法

回答by gravy

Also, make sure you are not calling for FBSDKAccessToken.currentAccessTokenINSIDE your didFinishLaunchingWithOptionsmethod. The setup in didFinishLaunchingWithOptionsneeds to complete so the token can initialize before you try to log in to Facebook.

另外,请确保您没有在FBSDKAccessToken.currentAccessToken您的didFinishLaunchingWithOptions方法中调用INSIDE 。didFinishLaunchingWithOptions需要完成设置,以便令牌可以在您尝试登录 Facebook 之前初始化。