Подтвердить что ты не робот

FBSDKLoginManager logInWithPublishPermissions всегда возвращает isCancelled = ДА

Мне трудно понять, как зарегистрировать пользователя в моем приложении. [FBSDKAccessToken currentAccessToken] равен нулю, поэтому я звоню:

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

согласно прилагаемому образцу проекта. Это переключается на приложение Facebook, но в сообщении говорится: "У вас уже разрешено имя приложения". Я нажимаю OK, и он возвращается в приложение, но grantedPermissions и declinedPermissions являются как nil для результата, а isCancelled - YES. [FBSDKAccessToken currentAccessToken] по-прежнему nil.

Я не могу понять, как мне нужно заполнить currentAccessToken. Мне кажется, что вызов logInWithPublishPermissions должен сделать это, но это не так.

4b9b3361

Ответ 1

Вам следует попробовать добавить в AppDelegate doneFinishLaunchingWithOptions:

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

При входе пользователя в систему будет получен 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

Ответ 2

Это может произойти, если ваше приложение Facebook не имеет разрешения "publish_actions", или вы не используете тестового пользователя.

В Facebook перейдите, чтобы управлять своим приложением, а затем убедитесь, что пользователь Facebook, которого вы используете, определяется в разделе "Роли" в качестве администратора или тестера.

Если это не тестовый пользователь или администратор - Facebook потребует, чтобы разрешение "publish_actions" было проверено и одобрено, прежде чем разрешить вашему приложению использовать его, до тех пор вы получите результат "isCancelled = YES".

После тестирования вашего приложения с этим разрешением вы можете отправить это разрешение для просмотра, вам нужно будет загрузить двоичный файл, который демонстрирует использование этого разрешения с точными подробностями о том, как его использовать. После того, как он будет одобрен, вы сможете использовать его с пользователями, не прошедшими проверку Facebook.

Ответ 3

Поскольку FBSDKLoginKit 4.6.0, методы logInWithReadPermissions и logInWithPublishPermissions FBSDKLoginManager, похоже, имеют дополнительный аргумент fromViewController и используют это для представления модалов.

Я вызывал logInWithPublishPermissions внутри обратного вызова logInWithReadPermissions, который в этот момент модально еще не уволен. (Я знаю, что это плохая практика, чтобы спросить разрешения, когда это не нужно, но в моем случае это, кажется, подходящее место для этого.) Это приводит к сбою с isCancelled равным YES. Я добавил некоторую задержку и дождался, когда модальный будет полностью уволен, исправил проблему.

Ответ 4

У меня была такая же проблема, когда я приземлился здесь, оказывается, я использовал только метод openURL для устаревших приложений, потому что я тоже пользовался значком google. Для поддержки 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: Так как быстрое изменение состояния метода может изменяться, я предлагаю вам всегда использовать автоматическое завершение из XCode при переопределении и реализации метода делегата.

Надеюсь, что это поможет o/

Ответ 5

Этот метод работает в 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. Это, безусловно, будет работать

Ответ 6

Кроме того, убедитесь, что вы не вызываете FBSDKAccessToken.currentAccessToken INSIDE ваш метод didFinishLaunchingWithOptions. Настройка в didFinishLaunchingWithOptions должна завершиться так, чтобы токен мог инициализироваться, прежде чем пытаться войти в Facebook.

Ответ 7

FBSDKLoginManagerLoginResult.isCancelled неожиданно YES:

SDK сообщит об аннулировании, если пользователь явно нажал кнопку отмены в диалоговых окнах входа в систему или же они вручную переключились обратно в ваше приложение (известное как скрытое отмена). Вы должны убедиться, что вы не инициируете поток входа в качестве части жизненного цикла приложения delegate (например, запустите вход в систему application:openURL:sourceApplication:annotation:), поскольку это будет имитировать неявное отмена. Если необходимо, отправьте инициацию входа позже в основную очередь, чтобы первый жизненный цикл делегирования приложения завершился.

Ответ 8

Я также столкнулся с той же проблемой, и я потратил почти 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 

и проблема была исправлена.

Я использовал оба входа в 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;
}

//вы можете выполнять любые операции с использованием токена доступа

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

Ответ 9

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

Ответ 10

назовите этот метод,

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