FaceBook SDK3.5 closeAndClearTokenInformation вызывает обработчик завершения openActiveSessionWithReadPermissions

У меня есть следующий код, который я использую во время входа в facebook.

- (BOOL)openFBSessionWithAllowLoginUI:(BOOL)allowLoginUI
            withCompletionHandler:(void (^)())completionHandler
{

    NSArray *permissions = [NSArray arrayWithObjects:
                        @"user_photos",
                        @"email",
                        nil];
    return [FBSession openActiveSessionWithReadPermissions:permissions allowLoginUI:allowLoginUI completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
       if (error != nil) {
        ...
       } else {
            switch (state) {
               case FBSessionStateOpen:
               {
                   ...
               }
               case FBSessionStateClosed:
               {
                   ...
               }
               case FBSessionStateClosedLoginFailed:
               {
                   ...
               }
               default:
                   break;
           }
       }
   }];
}

Вышеуказанное работает отлично для входа. Но, когда я выхожу из системы, используя следующий код

[FBSession.activeSession closeAndClearTokenInformation];

это снова вызывает завершениеHandler openActiveSessionWithReadPermissions: разрешения allowLoginUI:. Это не имеет смысла для меня. Я не думаю, что это правильное поведение. Кто-нибудь видел эту проблему? Как мы выходим из системы? Я использую SDK 3.5 на iOS6.

Ответ 1

В соответствии с этот поток в отслеживателе ошибок разработчиков Facebook, это поведение "по дизайну".

Фактически, я предположил, что лучшим именем для этого метода будет: openActiveSessionWithReadPermissions:allowLoginUI:stateChangeHandler:

поскольку это более точно описывает то, что происходит ( "completeHandler" на самом деле вызван изменением состояния).

Вы можете справиться с этим несколькими способами: Ben Cohen предлагают установить completionHandler в nil в блок завершения (чтобы гарантировать, что run-once), этот ответ предлагает создать обработчик run-once FBSessionStateHandler или вы можете включить изменение состояния.

В идеале, поскольку мы полагаемся на SDK для определенных целей (войдите в систему, выйдите из системы, сделайте запросы и т.д.), они будут предоставлены через делегатов, но поскольку разработчики SDK, видимо, немного увлеклись "ooh блоков!", вам остается определить свой обработчик изменения состояния в том месте, где вы сначала открываете сеанс.

Ответ 2

Это очень плохое поведение, я думаю.

FBSession имеет скрытое свойство:

@property (readwrite, copy) FBSessionStateHandler loginHandler;

Таким образом, вы можете установить его на нуль этим кодом в блоке следующим образом:

[FBSession openActiveSessionWithReadPermissions:FACEBOOK_PERMISSIONS
                                           allowLoginUI:NO
                                      completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
                                          [[FBSession activeSession] performSelector:NSSelectorFromString(@"setLoginHandler:") withObject:nil];
#pragma clang diagnostic pop
                                          // Your stuff...
                                      }];