ios - fbsdkloginkit - FBSDKLoginManager logInWithPublishPermissions siempre devuelve isCancelled=YES
fbsdkcorekit (10)
Tengo problemas para descubrir cómo registrar un usuario en mi aplicación. [FBSDKAccessToken currentAccessToken]
es nulo, entonces estoy llamando:
[[[FBSDKLoginManager alloc] init] logInWithPublishPermissions:@[@"publish_actions"] handler:…];
según el proyecto de muestra incluido. Esto cambia a la aplicación de Facebook, pero el mensaje dice "Ya has autorizado el nombre de la aplicación ". Hago clic en Aceptar y vuelve a entrar en la aplicación, pero grantedPermissions
y grantedPermissions
son nil
en el resultado, y está isCancelled
es YES
. [FBSDKAccessToken currentAccessToken]
sigue siendo nil
.
No puedo entender cómo se supone que currentAccessToken
completar currentAccessToken
. Me parece que la llamada a logInWithPublishPermissions
debería hacer eso, pero no es así.
Además, asegúrese de no llamar a FBSDKAccessToken.currentAccessToken
DENTRO de su método didFinishLaunchingWithOptions
. La configuración en didFinishLaunchingWithOptions
debe completarse para que el token pueda inicializarse antes de intentar iniciar sesión en Facebook.
Debería intentar agregar en su AppDelegate didFinishLaunchingWithOptions:
return [[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
Esto te pondría a [FBSDKAccessToken currentAccessToken]
cuando el usuario haya iniciado sesión.
y
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}
Si este método no está presente en AppDelegate, resulta en estado cancelado.
Consulte: https://developers.facebook.com/docs/ios/getting-started#startcoding
Desde FBSDKLoginKit 4.6.0, los métodos logInWithReadPermissions
y logInWithPublishPermissions
de FBSDKLoginManager parecen tener un argumento adicional fromViewController
y lo usan para presentar modals.
Estaba llamando a logInWithPublishPermissions
dentro de la devolución de llamada de logInWithReadPermissions
, que en ese momento el modal aún no se ha descartado por completo . (Sé que es una mala práctica pedir permiso cuando no es necesario, pero en mi caso este parece ser el lugar correcto para hacerlo). Esto causa que falle con isCancelled
es igual a YES. Agregué un poco de retraso y esperé a que el modal fuera completamente descartado solucionó el problema.
Esto puede suceder cuando su aplicación de Facebook no tiene el permiso "publish_actions" o no está utilizando un usuario de prueba .
En Facebook, ve a administrar tu aplicación, luego asegúrate de que el usuario de Facebook que estás utilizando esté definido en "Roles" como administrador o tester.
Si no es un usuario o administrador de prueba: Facebook requerirá que se revise y apruebe el permiso "publish_actions" antes de permitir que su aplicación lo use, hasta entonces recibirá un resultado "isCancelled = YES".
Después de probar su aplicación con este permiso, es posible enviar este permiso para su revisión, deberá cargar un archivo binario que demuestre el uso de este permiso con detalles exactos sobre cómo usarlo. Después de su aprobación, podrá usarlo con usuarios de Facebook que no sean de prueba.
También enfrenté el mismo problema y pasé casi 2 horas para resolver el problema. Lo que hice es
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
**[login logOut];** // adding this single line fixed my issue
[login logInWithReadPermissions: @[@"public_profile"] fromViewController:self handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error) {
NSLog(@"Process error");
} else if (result.isCancelled) {
NSLog(@"Cancelled");
} else {
NSLog(@"Logged in");
[self GetData];
}
}] // I called this logout function
y el problema fue arreglado
Estaba usando tanto el inicio de sesión de google como el de Facebook, así que tuve que implementar mi método openURL de esta manera, iOS 9+
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if ([[url absoluteString] containsString:@"YOURFBID"]) {
return [[FBSDKApplicationDelegate sharedInstance] application:app openURL:url options:options];
} else {
return [[GIDSignIn sharedInstance] handleURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];
}
return NO;
}
// puedes realizar más operaciones usando el token de acceso
- (void)GetData {
if ([FBSDKAccessToken currentAccessToken]) {
NSDictionary *AccessToken = [FBSDKAccessToken currentAccessToken];
[[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields": @"id, name, first_name, picture.type(large) ,last_name"}]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
//NSLog(@"fetched user:%@", result);
//NSDictionary *Result = result;
NSDictionary *params = [NSMutableDictionary dictionaryWithObject:[AccessToken tokenString] forKey:@"access_token"];
} else {
[self showAlertController:@"Error" message:error.localizedDescription];
}
}];
} }
Tuve el mismo problema cuando aterricé aquí, resulta que solo estaba usando el método obsoleto de la aplicación openURL porque también estaba usando el inicio de sesión de Google. Para admitir iOS 8 y antes, debe implementar el método actual y el método en desuso:
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return GIDSignIn.sharedInstance().handle(url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String!, annotation: options[UIApplicationOpenURLOptionsKey.annotation]) || FBSDKApplicationDelegate.sharedInstance().application(app, open: url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String, annotation: options[UIApplicationOpenURLOptionsKey.annotation])
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return GIDSignIn.sharedInstance().handle(url, sourceApplication: sourceApplication, annotation: annotation) || FBSDKApplicationDelegate.sharedInstance().application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
}
El obsoleto es el segundo.
Nota: El método FBSDK se agrega después de google con un o "||" operador, pero el orden no importa y si solo quiere utilizar el método facebook simplemente borre el método y el operador o.
Nota 2: como swift 3 sigue estabilizándose, el nombre del método puede cambiar. Le sugiero que siempre use el autocompletado de XCode al anular e implementar el método de un delegado.
Espero que esto ayude o /
llama este methord,
FBSDKLoginManager *loginManager = [[FBSDKLoginManager alloc] init];
[loginManager logInWithReadPermissions:@[@"user_friends"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
code
}];
FBSDKLoginManagerLoginResult.isCancelled
es inesperadamente YES
:
El SDK informará una cancelación si el usuario toca de forma explícita un botón de cancelar en los cuadros de diálogo de inicio de sesión, o si la aplicación vuelve a su aplicación manualmente (lo que se conoce como cancelación implícita). Debe asegurarse de no iniciar un flujo de inicio de sesión como parte del ciclo de vida de su delegate
aplicaciones (como iniciar un inicio de sesión dentro de la application:openURL:sourceApplication:annotation:
ya que eso imitará una cancelación implícita. Si es necesario, envíe la iniciación de inicio de sesión más tarde a la cola principal para que el ciclo de vida del delegado de la aplicación se complete primero.
Este método funciona en iOS 9
// Facebook Login Completion delegate
- (void)loginButton:(FBSDKLoginButton *)loginButton didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error
{
if (result){
NSLog(@"%@",result);
NSLog(@"%@",result.grantedPermissions);
[self getFacebookData:result];
}
}
- (void)getFacebookData:(FBSDKLoginManagerLoginResult *)result{
if (![result.grantedPermissions containsObject:@"email"])
{
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
login.loginBehavior = FBSDKLoginBehaviorWeb;
[login logInWithReadPermissions:@[@"email"] fromViewController:self handler:^(FBSDKLoginManagerLoginResult *result, NSError *error)
{
if (error)
{
// Process error
}
else if (result.isCancelled)
{
// Handle cancellations
}
else
{
if ([result.grantedPermissions containsObject:@"email"])
{
NSLog(@"result is:%@",result);
if ([FBSDKAccessToken currentAccessToken]) {
[[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields": @"first_name, last_name, email, id"}]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSLog(@"fetched user:%@", result);
[self registerWithFacebook:result];
}else{
NSLog(@"%@",error);
}
}];
}
}
}
}];
}else{
if ([FBSDKAccessToken currentAccessToken]) {
[[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields": @"first_name, last_name, email, id"}]
startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
if (!error) {
NSLog(@"fetched user:%@", result);
[self registerWithFacebook:result];
}else{
NSLog(@"%@",error);
}
}];
}
}
}
NOTA : utilice FBSDKLoginBehaviorWeb en lugar de FBSDKLoginBehaviorBrowser . Esto seguramente funcionará
(BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
options:options];
}
// **Still need this for iOS8**
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(nullable NSString *)sourceApplication
annotation:(nonnull id)annotation
{
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation];
}