Сбой авторизации 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}

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

 Kathrin Holweger12 окт. 2012 г., 16:14
Я нашел этот метод где-то здесь:[FBSettings setLoggingBehavior:[NSSet setWithObjects:FBLoggingBehaviorFBRequests, FBLoggingBehaviorFBURLConnections, FBLoggingBehaviorAccessTokens, FBLoggingBehaviorSessionStateTransitions, nil]];
 ill_always_be_a_warriors12 окт. 2012 г., 16:12
как вы включили ведение журнала FBSDKLog?
 ill_always_be_a_warriors12 окт. 2012 г., 16:03
Я думаю, что у меня та же проблема, что и у вас. Я непока не знаю каких-либо решений или обходных путей.
 Kathrin Holweger12 окт. 2012 г., 16:28
Кстати, мне кажется, сейчас это работает, хотя яЯ не уверен, почему. Я включил решение отэтот проблема в моем обработчике sessionStateChanged, но он все равно нет работа. Пока я не попробовал позже. По некоторым причинам поведение теперь выглядит следующим образом. Я переключаю текущего работающего пользователя FB на iOS, в приложении сессия открыта, но запрос не будет выполнен. При следующей попытке открывается новый сеанс с правильным токеном, и следующий запрос к FB будет работать.

Ответы на вопрос(6)

rs:-(void)fbResync но не работа для меня.

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

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

-(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.

Я тогда звоню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 и могу войти. Yay!

 jowie23 окт. 2012 г., 14:48
Кроме того, это выигралобыть обратно совместимым с iOS 5. И по какой-то причинеfbAccounts возвращает пустой массив для меня, даже на iOS 6.stackoverflow.com/a/12811583/190657
 thesummersign06 сент. 2013 г., 08:32
@jowie это происходит, если вы не разрешили ВАШЕ ПРИЛОЖЕНИЕ пользователю Facebook из настроек.
 jowie23 окт. 2012 г., 14:42
Возможно, лучше обернуть нижний блок кода в функцию, которая называется что-то вродеfbAttemptConnection а затем использовать[self performSelector:@selector(fbAttemptConnection) withObject:nil afterDelay:0.5] Вместо того, чтобы использоватьsleepForTimeInterval: и блокировка потока.
 Kaigi29 мая 2013 г., 19:37
Вместо того, чтобы использовать какую-либо задержку, создайте блок завершения для вызова fbResync внутри([accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {}];), Единственное предостережение в том, что если выВызывая любые методы в FBSession, они должны происходить в основном потоке, но этолегко решить, обернув этот метод в[[NSOperationQueue mainQueue] addOperationWithBlock:^ {}]

ноль или адрес электронной почты " в "[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;
         }
     }];
}
</fbgraphuser>
 Read Q07 мар. 2013 г., 07:41
Это сработало для меня! Как вы на самом деле устанавливаете разрешения, которые вам требуются в любом случае?



У меня такая же проблема на 3.1.3 FB SDK с iOS7.1. И я нахожу решение здесь. Надеюсь, это поможет!

Я перепробовал все ответы здесь.

@loganathan nil permissions, @ill_always_be_a_warriors fbResync.

Все эти нея не работаю



Но я обнаружил, что он будет хорошо работать, когда я запускаю тот же код в симуляторе iPhone 7.1

(без ССО "Единая точка входа")



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

(но SSO не покажет при попытке войти)



Итак, я пытаюсь переписать пример задачи. Я нашел несколько разных здесь.

1.https://developers.facebook.com/docs/ios/getting-started Добавить новый FacebookDisplayName

2. Я изменяю свой BundleID для подключения iTune, но я не обновляю его до Faceboook App Dev





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

Надеюсь, это поможет!

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

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

 Pierre-Olivier Simonard09 мар. 2013 г., 00:47
И проверьте также, что у вас есть последняя версия Facebook iOS SDK
 André Cytryn16 апр. 2013 г., 20:23
У меня была такая же проблема, и я сводил с ума. Впервые приложение открылось, я коснулся "не разрешать когда он спросил меня о разрешениях Facebook для целей тестирования. После этого он больше не появлялся. По крайней мере, я смог включить его снова в настройках iPhone.

Ваш ответ на вопрос