Ответ 1
Я включаю в себя класс утилиты Facebook, который я написал, который помогает с пониманием состояния входа в систему, потому что я предоставляю пользователю сообщение "вошел в систему" / "не вошел в систему" в моем собственном пользовательском интерфейсе настроек, в дополнение к использованию фактического "FBLoginView", когда приходит время, чтобы пользователь мог переключать состояние авторизации.
Код ниже также доступен через gist.
Я, возможно, не правильно интерпретировал все типы FBSessionState
в моем операторе switch, но до сих пор он хорошо меня обслуживал в тех случаях, когда я тестировал (я только что поставил это вместе).
Ключевое замечание, о котором говорили другие, заключается в том, что иногда у вас есть кеш-авторизация авторизации, которую вы не можете использовать сразу, но если вы сделаете вызов Facebook open
, вы можете получить ее быть повторно используемым (обновляется). Этот открытый вызов работает за кулисами, не вызывая переключения UI/jarring OAuth/приложения (если у вас есть кешированный токен).
См. мои комментарии в методе isLoggedInAfterOpenAttempt
. Обратите внимание, как я проверяю состояние FBSessionStateCreatedTokenLoaded
и только тогда, сделайте вызов
-openWithCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error)
.
Другие лакомые кусочки об этом классе:
- У меня есть свойство кэшировать зарегистрированного пользователя, типа, соответствующего протоколу
FBGraphUser
. Тем не менее, он не используется ни в одном из методов входа, показанных здесь. - В SDK 3.0 для кода примера iOS предлагается создать свой собственный класс для управления этими видами операций, если у вас есть что-то большее, чем простое приложение. Этот мой класс ниже - это начало этой идеи для моего приложения.
- Вы можете заменить мои макросы "log4Info" и "log4Debug" на NSLog, чтобы заставить это работать.
#import "UWFacebookService.h" @implementation UWFacebookService // Static static const int ddLogLevel = LOG_LEVEL_DEBUG; // Strong @synthesize facebookGraphUser = _facebookGraphUser; #pragma mark - Inquiries - (BOOL)isSessionStateEffectivelyLoggedIn:(FBSessionState)state { BOOL effectivelyLoggedIn; switch (state) { case FBSessionStateOpen: log4Info(@"Facebook session state: FBSessionStateOpen"); effectivelyLoggedIn = YES; break; case FBSessionStateCreatedTokenLoaded: log4Info(@"Facebook session state: FBSessionStateCreatedTokenLoaded"); effectivelyLoggedIn = YES; break; case FBSessionStateOpenTokenExtended: log4Info(@"Facebook session state: FBSessionStateOpenTokenExtended"); effectivelyLoggedIn = YES; break; default: log4Info(@"Facebook session state: not of one of the open or openable types."); effectivelyLoggedIn = NO; break; } return effectivelyLoggedIn; } /** * Determines if the Facebook session has an authorized state. It might still need to be opened if it is a cached * token, but the purpose of this call is to determine if the user is authorized at least that they will not be * explicitly asked anything. */ - (BOOL)isLoggedIn { FBSession *activeSession = [FBSession activeSession]; FBSessionState state = activeSession.state; BOOL isLoggedIn = activeSession && [self isSessionStateEffectivelyLoggedIn:state]; log4Info(@"Facebook active session state: %d; logged in conclusion: %@", state, (isLoggedIn ? @"YES" : @"NO")); return isLoggedIn; } /** * Attempts to silently open the Facebook session if we have a valid token loaded (that perhaps needs a behind the scenes refresh). * After that attempt, we defer to the basic concept of the session being in one of the valid authorized states. */ - (BOOL)isLoggedInAfterOpenAttempt { log4Debug(@"FBSession.activeSession: %@", FBSession.activeSession); // If we don't have a cached token, a call to open here would cause UX for login to // occur; we don't want that to happen unless the user clicks the login button over in Settings, and so // we check here to make sure we have a token before calling open if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) { log4Info(@"We have a cached token, so we're going to re-establish the login for the user."); // Even though we had a cached token, we need to login to make the session usable: [FBSession.activeSession openWithCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error) { log4Info(@"Finished opening login session, with state: %d", status); }]; } else { log4Info(@"Active session wasn't in state 'FBSessionStateCreatedTokenLoaded'. It has state: %d", FBSession.activeSession.state); } return [self isLoggedIn]; } @end