Авторизация Facebook не работает на iOS6 при переключении учетной записи FB на устройстве

Я использую Facebook SDK 3.1.1 для реализации FB Connect в моем приложении iOS. Это отлично работает в простом случае либо с новой интеграцией FB (вход в систему на iOS), либо с возвратом к обычной авторизации через веб-просмотр (у меня нет собственного приложения Facebook, установленного в обоих случаях). Проблема возникает, когда я переключаю учетную запись на уровень iOS. Выход из системы и вход в систему с другой учетной записью пользователя FB.

Для входа / авторизации выполняю:

[FBSession openActiveSessionWithReadPermissions:nil allowLoginUI:allowLoginUI
                                     completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
                                         [self sessionStateChanged:session state:state error:error];
                                     }];

Если затем каждый раз получать FBSessionStateClosedLoginFailed, даже если я выполняю closeAndClearTokenInformation, когда это состояние достигается:

- (void)sessionStateChanged:(FBSession *)session
                  state:(FBSessionState) state
                  error:(NSError *)error
{
    NSLog(@"Session State Changed: %u", [[FBSession activeSession] state]);
    switch (state) {
        case FBSessionStateOpen:
            break;
        case FBSessionStateClosed:
        case FBSessionStateClosedLoginFailed:
            NSLog(@"FBSessionStateClosedLoginFailed ERROR: %@", [error description]);
            [[FBSession activeSession] closeAndClearTokenInformation];
            break;
        default:
            break;
}

Однако я получаю одно и то же состояние при каждой повторной попытке. В моем журнале написано следующее:

FBSDKLog: FBSession **INVALID** transition from FBSessionStateCreated to FBSessionStateClosed
FBSDKLog: FBSession transition from FBSessionStateCreated to FBSessionStateCreatedOpening 
FBSDKLog: FBSession transition from FBSessionStateCreatedOpening to FBSessionStateClosedLoginFailed Session State Changed: 257
FBSessionStateClosedLoginFailed TOKEN: (null)
FBSessionStateClosedLoginFailed ERROR: Error Domain=com.facebook.sdk Code=2 "The operation couldn’t be completed. (com.facebook.sdk error 2.)" UserInfo=0xb24cc20 {com.facebook.sdk:ErrorLoginFailedReason=com.facebook.sdk:ErrorLoginFailedReason}

Может ли кто-нибудь воспроизвести это или имеет какое-либо представление, в чем может заключаться проблема?


person Kathrin Holweger    schedule 11.10.2012    source источник
comment
Я думаю, что у меня такая же проблема, как и у вас. Я пока не знаю никаких решений или обходных путей.   -  person ill_always_be_a_warriors    schedule 12.10.2012
comment
как ты включил ведение журнала FBSDKLog?   -  person ill_always_be_a_warriors    schedule 12.10.2012
comment
Я нашел этот метод где-то здесь: [FBSettings setLoggingBehavior:[NSSet setWithObjects:FBLoggingBehaviorFBRequests, FBLoggingBehaviorFBURLConnections, FBLoggingBehaviorAccessTokens, FBLoggingBehaviorSessionStateTransitions, nil]];   -  person Kathrin Holweger    schedule 12.10.2012
comment
Кстати, похоже, сейчас это работает для меня, хотя я не уверен, почему. Я включил решение из этой проблемы в свой обработчик sessionStateChanged, но это все равно не сработает. Пока я не попробовал позже. По какой-то причине поведение теперь выглядит следующим образом. Я переключаю текущего работающего пользователя FB на iOS, в приложении сеанс открыт, но запрос не выполняется. При следующей попытке открывается новый сеанс с правильным токеном, и следующий запрос к FB будет работать.   -  person Kathrin Holweger    schedule 12.10.2012


Ответы (6)


Другой ответ дает возможность вручную повторно синхронизировать устройство с сервер. Я определил метод fbRsync для вызова этого кода. Убедитесь, что #import <Accounts/Accounts.h> в вашем файле реализации, а затем определите этот метод:

-(void)fbResync
{
    ACAccountStore *accountStore;
    ACAccountType *accountTypeFB;
    if ((accountStore = [[ACAccountStore alloc] init]) && (accountTypeFB = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook] ) ){

    NSArray *fbAccounts = [accountStore accountsWithAccountType:accountTypeFB];
    id account;
    if (fbAccounts && [fbAccounts count] > 0 && (account = [fbAccounts objectAtIndex:0])){

    [accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {
        //we don't actually need to inspect renewResult or error.
        if (error){

        }
    }];
}

}

Затем я вызываю fbResync, если openActiveSessionWithReadPermissions дает ошибку:

[FBSession openActiveSessionWithReadPermissions:permissions
                                   allowLoginUI:YES
                              completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
     if(error)
     {
         NSLog(@"Session error");
         [self fbResync];
         [NSThread sleepForTimeInterval:0.5];   //half a second
         [FBSession openActiveSessionWithReadPermissions:permissions
                                            allowLoginUI:YES
                                       completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
            [self sessionStateChanged:session state:state error:error];
                                       }];

     }
     else
         [self sessionStateChanged:session state:state error:error];
 }];

Задержка в полсекунды, вероятно, не нужна, но в настоящее время она дает мне уверенность.

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

person ill_always_be_a_warriors    schedule 12.10.2012
comment
Возможно, лучше обернуть нижний блок кода в функцию, называемую чем-то вроде fbAttemptConnection, а затем использовать [self performSelector:@selector(fbAttemptConnection) withObject:nil afterDelay:0.5] вместо использования sleepForTimeInterval: и блокировки потока. - person jowie; 23.10.2012
comment
Кроме того, это не будет обратно совместимо с iOS 5. И по какой-то причине fbAccounts возвращает мне пустой массив, даже на iOS 6. stackoverflow.com/a/12811583/190657 - person jowie; 23.10.2012
comment
Вместо использования какой-либо задержки создайте блок завершения для вызова fbResync внутри ([accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {<here>}];). Единственное предостережение: если вы вызываете какие-либо методы в сеансе FBSession, они должны выполняться в основном потоке, но это легко решить, заключив этот метод в [[NSOperationQueue mainQueue] addOperationWithBlock:^ {<here>}] - person Kaigi; 29.05.2013
comment
@jowie это происходит, если вы не разрешили ВАШЕМУ ПРИЛОЖЕНИЮ доступ к пользователю facebook в настройках. - person thesummersign; 06.09.2013

У меня такая же проблема. Убедитесь, что ваше приложение FB включено в Настройки -> Facebook. Мой был отключен (хотя я не помню, как отключал его), и как только я его включил, это было исправлено.

В процессе тестирования я несколько раз добавлял и удалял приложение FB из своей учетной записи FB, которая связана с моим iPhone. Это может объяснить, почему волшебным образом мое приложение было отключено.

person Pierre-Olivier Simonard    schedule 08.03.2013
comment
Также убедитесь, что у вас последняя версия Facebook iOS SDK. - person Pierre-Olivier Simonard; 09.03.2013
comment
У меня была такая же проблема, и я сходил с ума. В первый раз, когда приложение открылось, я коснулся кнопки «Не разрешать», когда оно попросило у меня разрешения на facebook в тестовых целях. После этого он больше никогда не появлялся. По крайней мере, мне удалось снова включить его в настройках iPhone. - person Andre Cytryn; 16.04.2013

В ios 6 с fb sdk 3.1.1. Пожалуйста, передайте параметр разрешений как «nil или email» в методе «[FBSessio openActiveSessionWithReadPermissions ...». Здесь мой код отлично работает.

#define IOS_NEWER_OR_EQUAL_TO_6 ( [ [ [ UIDevice currentDevice ] systemVersion ] floatValue ] >= 6.0 )

-(void)showFBLogin
{
    [FBSession.activeSession closeAndClearTokenInformation];

    NSArray *permissions = [NSArray arrayWithObjects:@"email, publish_actions, publish_stream", nil];

#ifdef IOS_NEWER_OR_EQUAL_TO_6
    permissions = nil; or NSArray *permissions = [NSArray arrayWithObjects:@"email",nil];
#endif

    NSLog(@"\npermissions = %@", permissions);
    [FBSession openActiveSessionWithReadPermissions:permissions
                                       allowLoginUI:YES
                                  completionHandler:
     ^(FBSession *session,
       FBSessionState state, NSError *error) {
         NSLog(@"\nfb sdk error = %@", error);
         switch (state) {
             case FBSessionStateOpen:
                 [[FBRequest requestForMe] startWithCompletionHandler:
                  ^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
                      if (!error) {
                          //success
                      } 
                  }];
                 break;
             case FBSessionStateClosed:
                 //need to handle
                 break;
             case FBSessionStateClosedLoginFailed:
                 //need to handle
                 break;
             default:
                 break;
         }
     }];
}
person loganathan    schedule 07.02.2013
comment
Это сработало для меня! Как вы на самом деле устанавливаете требуемые разрешения? - person Read Q; 07.03.2013


У меня такая же проблема с 3.1.3 FB SDK с iOS7.1. И здесь я нахожу решение. Надеюсь, это поможет !!
Я попробовал все ответы здесь.
@loganathan nil permissions, @ill_always_be_a_warriors fbResync.
Все это у меня не работает.

Но я нашел это будет хорошо работать, когда я запускаю тот же код в симуляторе iPhone 7.1
(без SSO «Единый вход»)

Тот же код хорошо работает в старой версии iOS FB SDK (не уверен, какая версия, но не 3.13)
(но при попытке входа в систему система единого входа не отображается)

Итак, я пытаюсь переписать пример проблемы. Я нашел здесь несколько разных.
1. https://developers.facebook.com/docs/ios/getting-started Добавить новое имя FacebookDisplayName
2. Я изменяю свой BundleID для подключения к iTune, но не обновляю его до Faceboook App Dev


После изменения этих настроек , он работает в моем приложении iOS с функцией единого входа.
Надеюсь, это поможет !!

person Evan Lin    schedule 24.03.2014

Вы пробовали методы RenewSystemCredential? Взгляните на этот пост:

< / а>

person Hernan Arber    schedule 21.05.2013

У меня такая же ошибка. Но я использовал метод @ill_always_be_a_warriors: -(void)fbResync, но у меня не работает.

Я наконец обнаружил, что это моя проблема с разрешениями, я удалил offline_access разрешение, оно работает, надеюсь, это кому-то поможет.

person William Hu    schedule 21.01.2014