web-dev-qa-db-fra.com

FBSDKLoginManager logInWithPublishPermissions renvoie toujours isCancelled = YES

Je ne parviens pas à comprendre comment connecter un utilisateur à mon application. [FBSDKAccessToken currentAccessToken] est nul, alors je vous appelle:

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

selon l'exemple de projet inclus. Ceci bascule vers l'application Facebook, mais le message indique "Vous avez déjà autorisé Nom de l'application .". Je clique sur OK et revient dans l'application, mais grantedPermissions et declinedPermissions sont tous les deux nil sur le résultat et isCancelled est YES. [FBSDKAccessToken currentAccessToken] est toujours nil.

Je n'arrive pas à comprendre comment je suis censé obtenir currentAccessToken à remplir. Il me semble que l'appel à logInWithPublishPermissions devrait le faire, mais ce n'est pas le cas.

26
devios1

Vous devriez essayer d’ajouter à votre AppDelegate didFinishLaunchingWithOptions:

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

Cela donnerait u [FBSDKAccessToken currentAccessToken] lorsque l'utilisateur est connecté.

et 

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

Si cette méthode n'est pas présente dans AppDelegate, son état est alors annulé.

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

49
Dheeraj Singh

Cela peut se produire lorsque votre application Facebook ne dispose pas de l'autorisation "Publier_actions" ou vous n'utilisez pas d'utilisateur test.

Sur Facebook, accédez à votre application, puis assurez-vous que l'utilisateur Facebook que vous utilisez est défini sous "Rôles" en tant qu'administrateur ou testeur. 

Si ce n'est pas un utilisateur test ou un administrateur, Facebook devra passer en revue et approuver l'autorisation "publish_actions" avant de permettre à votre application de l'utiliser. Jusqu'à cette date, vous recevrez un résultat "isCancelled = YES".

Après avoir testé votre application avec cette autorisation, il est possible de soumettre cette autorisation pour révision. Vous devez alors télécharger un fichier binaire qui illustre l'utilisation de cette autorisation avec des détails exacts sur son utilisation. Une fois approuvé, vous pourrez l'utiliser avec des utilisateurs Facebook non testés.

29
Kof

J'ai eu le même problème lorsque j'ai atterri ici. Il s'avère que je n'utilisais que la méthode openURL, une application obsolète, car j'utilisais également Google Sign in. Pour prendre en charge iOS 8 et les versions antérieures, vous devez implémenter les méthodes actuelle et obsolète:

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)
}

Le obsolète est le second.

Remarque: La méthode FBSDK est ajoutée à la suite de celle de Google avec un "||". opérateur, mais l'ordre n'a pas d'importance et si vous voulez utiliser uniquement la méthode facebook, effacez simplement la méthode et l'opérateur ou. 

Remarque 2: étant donné que Swift 3 peut encore changer, le nom de la méthode peut être modifié. Je vous suggère de toujours utiliser l'auto-complétion à partir de XCode lors de la substitution et de l'implémentation d'une méthode de délégué.

J'espère que cela aide o /

Depuis FBSDKLoginKit 4.6.0, les méthodes logInWithReadPermissions et logInWithPublishPermissions de FBSDKLoginManager semblent avoir un argument supplémentaire fromViewController et l’utiliser pour présenter les modaux. 

J'appelais logInWithPublishPermissions à l'intérieur du rappel de logInWithReadPermissions, qui à ce moment le modal n'est pas encore complètement rejeté . (Je sais que c'est une mauvaise pratique de demander la permission quand ce n'est pas nécessaire, mais dans mon cas, cela semble être le bon endroit à faire.) Cela provoque un échec avec isCancelled égal à OUI. J'ai ajouté un peu de retard et attendre que le modal soit complètement rejeté a résolu le problème.

2
Hlung

Cette méthode fonctionne sous 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: Utilisez FBSDKLoginBehaviorWeb au lieu de FBSDKLoginBehaviorBrowser . Cela fonctionnera sûrement

1
jaya raj
(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];
}
0
Cong Wang

1.check déjà ajouté 

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

2.check déjà ajouté

- (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 . Écrivez cette déclaration [FBSDKProfile enableUpdatesOnAccessTokenChange:YES]; Avant 

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

4.call méthode logInWithReadPermissions dans dispatch_after (dispatch_time (DISPATCH_TIME_NOW, (int64_t) (1 * NSEC_PER_SEC)), dispatch_get_main_queue (), ^ {}

0
Yong Piao

FBSDKLoginManagerLoginResult.isCancelled est inopinément YES:

Le SDK signalera une annulation si l'utilisateur appuie explicitement sur un bouton d'annulation dans les boîtes de dialogue de connexion ou s'il rétablit manuellement l'application sur votre application (annulation implicite). Vous devez vous assurer que vous n'initiez pas de flux de connexion dans le cadre du cycle de vie de votre application delegate (par exemple, le démarrage d'une connexion dans application:openURL:sourceApplication:annotation:), car cela imiterait une annulation implicite. Si vous devez le faire, répartissez l'initialisation de la connexion ultérieurement dans la file d'attente principale afin que le cycle de vie du délégué de l'application se termine en premier.

0
Salman Ghumsani

Assurez-vous également que vous n'appelez pas pour FBSDKAccessToken.currentAccessToken INSIDE dans votre méthode didFinishLaunchingWithOptions. La configuration dans didFinishLaunchingWithOptions doit être terminée pour que le jeton puisse s'initialiser avant d'essayer de vous connecter à Facebook.

0
gravy

J'ai également fait face au même problème et j'ai passé presque deux heures à résoudre le problème. Ce que j'ai fait c'est 

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 

et le problème a été résolu

j'utilisais à la fois google et Facebook, je devais donc implémenter ma méthode openURL comme celle-ci, 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;
}

// vous pouvez effectuer d'autres opérations en utilisant le jeton d'accès 

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