Je ne parviens pas à comprendre comment connecter un utilisateur à mon application. [FBSDKAccessToken currentAccessToken]
est nul, alors je vous appelle:
[[[FBSDKLoginManager alloc] init] logInWithPublishPermissions:@[@"publish_actions"] handler:…];
selon l'exemple de projet inclus. Ceci bascule vers l'application Facebook, mais le message indique "Vous avez déjà autorisé Nom de l'application .". Je clique sur OK et revient dans l'application, mais grantedPermissions
et declinedPermissions
sont tous les deux nil
sur le résultat et isCancelled
est YES
. [FBSDKAccessToken currentAccessToken]
est toujours nil
.
Je n'arrive pas à comprendre comment je suis censé obtenir currentAccessToken
à remplir. Il me semble que l'appel à logInWithPublishPermissions
devrait le faire, mais ce n'est pas le cas.
Vous devriez essayer d’ajouter à votre AppDelegate didFinishLaunchingWithOptions:
return [[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
Cela donnerait u [FBSDKAccessToken currentAccessToken]
lorsque l'utilisateur est connecté.
et
- (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 cette méthode n'est pas présente dans AppDelegate, son état est alors annulé.
Voir: https://developers.facebook.com/docs/ios/getting-started#startcoding
Cela peut se produire lorsque votre application Facebook ne dispose pas de l'autorisation "Publier_actions" ou vous n'utilisez pas d'utilisateur test.
Sur Facebook, accédez à votre application, puis assurez-vous que l'utilisateur Facebook que vous utilisez est défini sous "Rôles" en tant qu'administrateur ou testeur.
Si ce n'est pas un utilisateur test ou un administrateur, Facebook devra passer en revue et approuver l'autorisation "publish_actions" avant de permettre à votre application de l'utiliser. Jusqu'à cette date, vous recevrez un résultat "isCancelled = YES".
Après avoir testé votre application avec cette autorisation, il est possible de soumettre cette autorisation pour révision. Vous devez alors télécharger un fichier binaire qui illustre l'utilisation de cette autorisation avec des détails exacts sur son utilisation. Une fois approuvé, vous pourrez l'utiliser avec des utilisateurs Facebook non testés.
J'ai eu le même problème lorsque j'ai atterri ici. Il s'avère que je n'utilisais que la méthode openURL, une application obsolète, car j'utilisais également Google Sign in. Pour prendre en charge iOS 8 et les versions antérieures, vous devez implémenter les méthodes actuelle et obsolète:
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)
}
Le obsolète est le second.
Remarque: La méthode FBSDK est ajoutée à la suite de celle de Google avec un "||". opérateur, mais l'ordre n'a pas d'importance et si vous voulez utiliser uniquement la méthode facebook, effacez simplement la méthode et l'opérateur ou.
Remarque 2: étant donné que Swift 3 peut encore changer, le nom de la méthode peut être modifié. Je vous suggère de toujours utiliser l'auto-complétion à partir de XCode lors de la substitution et de l'implémentation d'une méthode de délégué.
J'espère que cela aide o /
Depuis FBSDKLoginKit 4.6.0, les méthodes logInWithReadPermissions
et logInWithPublishPermissions
de FBSDKLoginManager semblent avoir un argument supplémentaire fromViewController
et l’utiliser pour présenter les modaux.
J'appelais logInWithPublishPermissions
à l'intérieur du rappel de logInWithReadPermissions
, qui à ce moment le modal n'est pas encore complètement rejeté . (Je sais que c'est une mauvaise pratique de demander la permission quand ce n'est pas nécessaire, mais dans mon cas, cela semble être le bon endroit à faire.) Cela provoque un échec avec isCancelled
égal à OUI. J'ai ajouté un peu de retard et attendre que le modal soit complètement rejeté a résolu le problème.
Cette méthode fonctionne sous 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);
}
}];
}
}
}
NOTE: Utilisez FBSDKLoginBehaviorWeb au lieu de FBSDKLoginBehaviorBrowser . Cela fonctionnera sûrement
(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];
}
1.check déjà ajouté
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
2.check déjà ajouté
- (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];
}
3 . Écrivez cette déclaration [FBSDKProfile enableUpdatesOnAccessTokenChange:YES];
Avant
[[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
4.call méthode logInWithReadPermissions dans dispatch_after (dispatch_time (DISPATCH_TIME_NOW, (int64_t) (1 * NSEC_PER_SEC)), dispatch_get_main_queue (), ^ {}
FBSDKLoginManagerLoginResult.isCancelled
est inopinément YES
:
Le SDK signalera une annulation si l'utilisateur appuie explicitement sur un bouton d'annulation dans les boîtes de dialogue de connexion ou s'il rétablit manuellement l'application sur votre application (annulation implicite). Vous devez vous assurer que vous n'initiez pas de flux de connexion dans le cadre du cycle de vie de votre application delegate
(par exemple, le démarrage d'une connexion dans application:openURL:sourceApplication:annotation:
), car cela imiterait une annulation implicite. Si vous devez le faire, répartissez l'initialisation de la connexion ultérieurement dans la file d'attente principale afin que le cycle de vie du délégué de l'application se termine en premier.
Assurez-vous également que vous n'appelez pas pour FBSDKAccessToken.currentAccessToken
INSIDE dans votre méthode didFinishLaunchingWithOptions
. La configuration dans didFinishLaunchingWithOptions
doit être terminée pour que le jeton puisse s'initialiser avant d'essayer de vous connecter à Facebook.
J'ai également fait face au même problème et j'ai passé presque deux heures à résoudre le problème. Ce que j'ai fait c'est
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
et le problème a été résolu
j'utilisais à la fois google et Facebook, je devais donc implémenter ma méthode openURL comme celle-ci, 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;
}
// vous pouvez effectuer d'autres opérations en utilisant le jeton d'accès
- (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];
}
}];
} }