2012-10-10 10 views
6

Sto aggiornando un'applicazione per utilizzare l'ultimo SDK di Facebook al fine di ottenere l'accesso al supporto nativo di Facebook iOS6. Attualmente utilizza una versione piuttosto vecchia dell'SDK di Facebook.Errore durante l'utilizzo di [FBSession openActiveSessionWithPublishPermissions: ..]

L'app richiede il permesso "publish_actions" da Facebook per l'unica cosa che fa con Facebook.

Inizialmente ho pensato che potrei usare [FBSession openActiveSessionWithPublishPermissions: ...] ma questo non funziona su iOS6 quando l'utente ha configurato Facebook nelle impostazioni di iOS6. Si riesce a causa di questo requisito, from the Facebook docs:

nota, utilizzare iOS 6 autenticazione nativa, app Hai bisogno di cambiare il modo in cui essi richiesta permessi da parte degli utenti - applicazioni devono separare le loro richieste di lettura e Scrittura. L'SDK di Facebook per iOS supporta queste funzioni e aiuta gli sviluppatori a utilizzarle per creare app che funzionano su più versioni di iOS e configurazioni di dispositivi.

Questa è una grande PITA, IMO. La nostra preferenza sarebbe quella di richiedere all'utente una volta il permesso e di farlo, ma il "nuovo" ideale per Apple/Facebook è quello di richiedere autorizzazioni specifiche nel contesto quando sono necessarie ma non ancora concesse.

Il piano al momento è di mantenere il nostro vecchio comportamento per gli utenti iOS5 e iOS6 che non hanno configurato Facebook in Impostazioni. E conforme al nuovo doppio prompt per gli utenti iOS6 che utilizzano l'accesso nativo.

La domanda è, qual è il modo migliore per farlo? Come devo sapere se l'SDK di Facebook selezionerà l'accesso nativo iOS6 rispetto ai meccanismi di fallback? Sto trascurando qualcosa di ovvio?

EDIT:

gerraldWilliam mi ha messo sulla strada giusta. La sua soluzione avrebbe quasi funzionato, tranne che ACAccountTypeIdentifierFacebook non è disponibile in iOS5. Inoltre, se l'utente blocca l'accesso FB in Impostazioni all'app, la chiamata accountsWithAccountType restituirà un array vuoto.

È possibile aggirare il primo problema chiedendo l'identificatore di corrispondenza del tipo di account "com.apple.facebook" - questo restituirà nullo su iOS5 e un oggetto di tipo account reale su iOS6.

Ma il secondo problema è irrisolvibile. Il mio nuovo piano è quello di aprire sempre la sessione iniziale su iOS6 con autorizzazioni di sola lettura e prompt più avanti, nel contesto, per il permesso di pubblicazione, se necessario. Su iOS5 aprirò comunque la sessione iniziale specificando l'autorizzazione publish_actions desiderata. Ecco il codice:

ACAccountStore* as = [[ACAccountStore new] autorelease]; 
ACAccountType* at = [as accountTypeWithAccountTypeIdentifier: @"com.apple.facebook"]; 
if (at != nil) { 
    // iOS6+, call [FBSession openActiveSessionWithReadPermissions: ...] 

} else { 
    // iOS5, call [FBSession openActiveSessionWithPublishPermissions: ...] 
} 

risposta

5
ACAccountStore *store = [[ACAccountStore alloc] init]; 

ACAccountType *accountType = [store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook]; 
NSArray *accounts = [store accountsWithAccountType:accountType]; 
NSLog(@"accounts:%@", accounts); 

se conti è pari a zero (o forse restituisce un array vuoto, non sono sicuro), quindi l'utente non ha configurato Facebook in iOS6. Puoi testarlo e se il valore indica che Facebook non è stato configurato per iOS6, puoi chiamare il meccanismo di fallback.

+0

Questo quasi funziona. Due problemi sono 1) ACAccountTypeIdentifierFacebook non è disponibile su iOS5 e 2) accountWithAccountType restituirà un array vuoto se l'utente ha configurato FB in Impostazioni ma ha bloccato l'accesso all'app chiamante. Segnando la risposta corretta in quanto mi ha messo sulla strada della mia ultima soluzione, che inserirò nella domanda. – TomSwift

+0

'accountsWithAccountType' restituisce una matrice vuota per me, anche se sono in iOS 6, l'integrazione di Facebook è stata configurata ed è possibile postare. – jowie

+0

Inoltre è vuoto per me, e ottiene questo errore fastidioso com.facebook.sdk errore 2 ... Qualche consiglio? – D33pN16h7

0

dispiace ma per me in iOS6 linea

ACAccountType* at = [as accountTypeWithAccountTypeIdentifier: @"com.apple.facebook"]; 

non restituisce nulla anche se l'utente non dispone di un account configurato ...

Il che significa che si può solo controllare qual è la versione di iOS dell'utente (5 o 6)

NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; 

This link può essere utile.

6

Sulla base di tutto ciò che ho letto sui siti degli sviluppatori di Facebook (che è in qualche modo contraddittorio) il flusso di lavoro di un'app "pubblica solo" non è qualcosa a cui hanno pensato molto e Apple/iOS sembra aver ignorato del tutto.

Facebook fornisce alcune indicazioni in docs you referenced:

Suggerimento 5: Disabilitare Login Dialog nativo

In alcuni casi, le applicazioni possono scegliere di disabilitare la finestra di dialogo nativa login per usare nuove versioni di Facebook SDK ma per evitare di riscrivere i modi in cui richiedono le autorizzazioni dagli utenti. Per utilizzare il comportamento precedente di fast-app-switch per l'accesso, utilizzare i metodi di FBSession deprecati openActiveSessionWithPermissions e reauthorizeWithPermissions.

Questo è il percorso che sto seguendo attualmente. Un po 'diverso, ma lo stesso effetto generale.

if (FBSession.activeSession.isOpen == NO) { 
    // This will bypass the ios6 integration since it does not allow for a session to be opened 
    // with publish only permissions! 
    FBSession* sess = [[FBSession alloc] initWithPermissions:[NSArray arrayWithObject:@"publish_actions"]]; 
    [FBSession setActiveSession:sess]; 
    [sess openWithBehavior:(FBSessionLoginBehaviorWithFallbackToWebView) completionHandler:^(FBSession *session, FBSessionState status, NSError *error) { 
     [self onSessionStateChange:session 
          andState:status 
          andError:error]; 
    }]; 

Il risultato è, l'applicazione sarà sempre bypassare l'integrazione IOS6 per la firma su per la pubblicazione, e nella maggior parte dei casi (poiché gli utenti in genere avranno già Facebook installato sul telefono) commutazione l'applicazione Facebook per un singolo approvazione dell'autorizzazione.

Se l'utente decide di accedere alla nostra app utilizzando il proprio account Facebook, chiamo openActiveSessionWithReadPermissions, che utilizzerà l'integrazione Facebook IOS6 se presente. Se successivamente decidono di condividere, quindi chiamo reauthorizeWithPublishPermissions che utilizzerà anche l'integrazione IOS6 se disponibile.

Data la documentazione minima e confusa disponibile non posso essere sicuro se questo è il modo "giusto" per avvicinarsi a questo, ma sembra funzionare. È possibile utilizzare lo stesso codice per un'app IOS5 o IOS6 poiché effettua solo chiamate tramite l'SDK di Facebook. Onora anche il fatto di non mischiare i permessi di lettura/pubblicazione nella stessa richiesta che Facebook sta ora promuovendo.

+0

Questo è quello che faccio pure io. Penso che sia di scarsa progettazione richiedere prima un'autorizzazione alla lettura e poi pubblicare in seguito.Se un utente desidera condividere una foto su Facebook nella mia app, preferirei autorizzarli tutti in una volta piuttosto che chiedere loro di accedere alla mia app utilizzando Facebook e poi chiedere nuovamente loro di autorizzare la condivisione quando vogliono condividere una foto. – jjxtra

+0

Howard, grazie per aver salvato la giornata – John

2

Invece di utilizzare seguente:

NSArray *readPermissions = [[NSArray alloc]   initWithObjects:@"email",@"friends_location",@"status_update",@"publish_actions",nil]; 
[FBSession openActiveSessionWithPublishPermissions:readPermissions defaultAudience:FBSessionDefaultAudienceEveryone allowLoginUI:YES completionHandler:^(FBSession *session, FBSessionState state, NSError *error) { 
//Your code here for handling forward things; 
} 

di questo codice:

NSArray *readPermissions = [[NSArray alloc] initWithObjects:@"email",@"friends_location",@"status_update",@"publish_actions",nil]; 
FBSession* sess = [[FBSession alloc] initWithPermissions:[NSArray arrayWithObject:readPermissions]]; 
[FBSession setActiveSession:sess]; 
[sess openWithBehavior:(FBSessionLoginBehaviorWithFallbackToWebView) completionHandler:^(FBSession *session, FBSessionState status, NSError *error) { 
    [self onSessionStateChange:session 
         andState:status 
         andError:error]; 

//Your code here for handling forward things; 

}]; 
Problemi correlati