2012-10-10 39 views
6

estoy actualizando una aplicación para utilizar la última Facebook SDK con el fin de obtener acceso al soporte nativo de Facebook iOS6. Actualmente usa una versión bastante antigua del SDK de Facebook.de error cuando se utiliza [openActiveSessionWithPublishPermissions FBSession: ..]

La aplicación requiere el permiso "publish_actions" de Facebook como la única cosa que hace con Facebook.

Al principio pensé que podría utilizar [FBSession openActiveSessionWithPublishPermissions: ...] pero esto no funciona en iOS 6, cuando el usuario ha configurado en la configuración de Facebook iOS6. Se produce un error debido a este requisito, from the Facebook docs:

Nota, para usar iOS 6 de autenticación nativa, aplicaciones necesitan cambiar la forma en que solicitan permisos de los usuarios - las aplicaciones deben separar sus solicitudes de lectura y escritura permisos . El SDK de Facebook para iOS admite estas características y ayuda a los desarrolladores a usarlas para crear aplicaciones que funcionen en múltiples versiones de iOS y configuraciones de dispositivos.

Este es un gran PITA, IMO. Nuestra preferencia sería solicitar una vez permiso al usuario y terminar con él, pero el "nuevo" ideal por Apple/Facebook es solicitar permisos específicos en contexto cuando se necesiten pero aún no se hayan otorgado.

El plan en este momento es mantener nuestro comportamiento de edad para los usuarios y usuarios iOS5 iOS6 que no tienen Facebook configurados en Configuración. Y cumpla con el nuevo doble aviso para usuarios de iOS6 que utilizan el acceso nativo.

La pregunta es, ¿cuál es la mejor manera de hacer esto? ¿Cómo debo proceder para detectar si el Facebook SDK seleccionará el inicio de sesión nativo iOS6 frente a los mecanismos de respaldo? ¿Estoy pasando por alto algo obvio?

EDIT:

gerraldWilliam me puso en el camino correcto. Su solución casi funcionaría, excepto que ACAccountTypeIdentifierFacebook no está disponible en iOS5. Además, si el usuario bloquea el acceso FB en Configuración a la aplicación, la llamada accountsWithAccountType devolverá una matriz vacía.

Es posible evitar el primer problema pidiendo el identificador de coincidencia de tipo de cuenta "com.apple.facebook" - esto devolverá nil en iOS5, y un objeto de tipo de cuenta real en iOS6.

Pero el segundo problema es irresoluble. Mi nuevo plan es abrir siempre la sesión inicial en iOS6 con permisos de solo lectura e indicar luego, en contexto, el permiso de publicación si es necesario. En iOS5, aún abriré la sesión inicial especificando el permiso publish_actions deseado. Aquí está el código:

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

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

Respuesta

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

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

si las cuentas es nulo (o tal vez devuelve una matriz vacía, no estoy seguro), entonces el usuario no ha configurado Facebook en iOS 6. Puede probarlo y si el valor indica que Facebook no se ha configurado para iOS6, puede llamar a su mecanismo alternativo.

+0

Esto casi funciona. Dos problemas son 1) ACAccountTypeIdentifierFacebook no está disponible en iOS5 y 2) accountsWithAccountType devolverá una matriz vacía si el usuario ha configurado FB en Configuración pero ha bloqueado el acceso a la aplicación de llamada. Marcar como la respuesta correcta ya que me puso en el camino hacia mi solución definitiva, que colocaré en la pregunta. – TomSwift

+0

'accountsWithAccountType' devuelve una matriz vacía para mí, incluso si estoy en iOS 6, la integración de Facebook se ha configurado y es posible publicar. – jowie

+0

También está vacío para mí, y obtiene este molesto error com.facebook.sdk error 2 ... ¿Algún consejo? – D33pN16h7

0

Lo sentimos, pero para mí en iOS6 la línea

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

no devuelve nada, incluso si el usuario no tiene una cuenta configurada ...

Lo que significa que sólo puede comprobar cuál es la versión de IOS de usuario (5 o 6)

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

This link puede ser útil.

6

Sobre la base de todo lo que he leído en los sitios programador de Facebook (que es algo contradictoria) el flujo de trabajo de un "publicar sólo" aplicación no es algo a lo que han pensado mucho, y Apple/IOS parece haber hecho caso omiso en total.

Facebook puede servir de orientación en el docs you referenced:

Consejo 5: Desactivación de la sesión de diálogo nativo

En algunos casos, las aplicaciones pueden optar por desactivar la sesión de diálogo nativo para utilizar las nuevas versiones del Facebook SDK pero para evitar reescribir las formas en que solicitan permisos de los usuarios. Para usar el comportamiento anterior de Fast-App-Switch para iniciar sesión, use los métodos de FBSession obsoletos openActiveSessionWithPermissions y reauthorizeWithPermissions.

Esta es la ruta que estoy siguiendo actualmente. Ligeramente diferente, pero el mismo efecto general.

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]; 
    }]; 

El resultado es, la aplicación siempre pasará por alto la integración IOS6 a la firma el de publicar, y en la mayoría de los casos (ya que normalmente los usuarios ya tendrán Facebook instalado en el teléfono) Conmutación a la aplicación de Facebook para un solo aprobación de auth

Si el usuario elige iniciar sesión en nuestra aplicación utilizando su cuenta de Facebook, llamo al openActiveSessionWithReadPermissions, que utilizará la integración de Facebook de IOS6, si está presente. Si posteriormente deciden compartir, entonces llamo al reauthorizeWithPublishPermissions, que también usará la integración de IOS6, si está disponible.

Dada la documentación mínima y confusa disponible, no puedo estar seguro de si esta es la forma "correcta" de abordar esto, pero parece funcionar. Puede usar el mismo código para una aplicación IOS5 o IOS6, ya que solo realiza llamadas a través del SDK de Facebook. También hace honor a la no mezcla de los permisos de lectura/publicación en la misma solicitud que Facebook está promocionando.

+0

Esto es lo que hago también. Creo que es un diseño deficiente requerir una autorización de lectura primero y luego publicarla más tarde.Si un usuario desea compartir una foto en Facebook en mi aplicación, preferiría autorizarlos de una sola vez en lugar de pedirles que inicien sesión en mi aplicación usando Facebook y luego pedirles nuevamente que autoricen el intercambio cuando quieran compartir una foto. – jjxtra

+0

Howard, gracias por salvarme el día – John

2

En lugar de utilizar siguiente:

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; 
} 

Usar este código:

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; 

}]; 
Cuestiones relacionadas