Includo una classe di utilità di Facebook che ho scritto che aiuta a capire lo stato di accesso, perché esporre un messaggio "connesso"/"non connesso" all'utente nella mia propria UI Impostazioni, oltre a utilizzare il componente "FBLoginView" effettivo quando arriva il momento di consentire all'utente di passare dallo stato di autorizzazione.
Il codice seguente è disponibile anche tramite questo gist.
Probabilmente non ho interpretato correttamente tutti i tipi FBSessionState
nella mia istruzione switch, ma finora mi è servito bene nei casi che ho testato (l'ho appena messo insieme).
La cosa fondamentale da notare, a cui altri hanno fatto riferimento, è che a volte si dispone di un token di autorizzazione memorizzato nella cache che non è possibile utilizzare immediatamente, ma se si effettua una chiamata su Facebook open
, è possibile ottenerlo riutilizzabile (aggiornato). Questa chiamata aperta funziona dietro le quinte, senza attivare alcuna commutazione di finestra/app OIuth/ostruzione dell'interfaccia utente (se si dispone di un token memorizzato nella cache).
Vedere i miei commenti nel metodo isLoggedInAfterOpenAttempt
. Nota come controllo lo stato da FBSessionStateCreatedTokenLoaded
e solo dopo, effettua la chiamata a
-openWithCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error)
.
Altre curiosità su questa classe:
- mi hanno una proprietà qui per memorizzare nella cache l'utente collegato, di tipo conforme al protocollo
FBGraphUser
. Tuttavia, non è utilizzato in nessuno dei metodi di accesso qui dimostrati.
- Il codice di esempio di Facebook SDK 3.0 per iOS suggerisce di costruire la propria classe per conservare e gestire questo tipo di operazioni, se si dispone di qualcosa di più di un'app banale. Questa classe di seguito è l'inizio di questa idea per la mia app.
- È possibile sostituire le mie macro 'log4Info' e 'log4Debug' con NSLog per farlo funzionare.
#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
Bisogna riaprire la sessione su ogni lancio app. –
Come si fa? Mi manca quella parte. sarebbe '[FBSession sessionOpenWithPermissions: ...]' a fare il trucco senza mostrare la finestra di autenticazione ogni volta? –
questo: '+ (BOOL) openActiveSessionWithAllowLoginUI: (BOOL) allowLoginUI' e anche Google FBSession - letteralmente il primo hit. –