web-dev-qa-db-fra.com

Facebook SDK v4.0 pour iOS - FBSDKProfile currentProfile non défini

Je viens de "mettre à niveau" mon SDK Facebook vers la version 4.0 pour mon application iOS. 

Je me connecte bien, mais d'après la documentation, je suis maintenant censé utiliser FBSDKProfile.currentProfile() pour accéder aux informations de profil. 

Cependant, cette valeur semble toujours être nil, même si ma photo de profil est affichée (par le biais d'une FBSDKProfilePictureView) et que ma FBSDKAccessToken.currentAccessToken() n'est pas nil

Ceci est mon identifiant ViewController:

import UIKit

class LoginViewController: UIViewController, FBSDKLoginButtonDelegate {

    @IBOutlet weak var fbLoginButton: FBSDKLoginButton!
    @IBOutlet weak var fbProfilePicture: FBSDKProfilePictureView! //displays a picture

    override func viewDidLoad() {
        super.viewDidLoad()
        self.fbLoginButton.delegate = self
        FBSDKProfile.enableUpdatesOnAccessTokenChange(true)
        if FBSDKAccessToken.currentAccessToken() != nil {
            println("\(FBSDKAccessToken.currentAccessToken().userID)") //works
        }
        self.fbLoginButton.readPermissions = ["public_profile", "email", "user_friends"]
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!) {
        println(FBSDKProfile.currentProfile()) //is nil
    }

    func loginButtonDidLogOut(loginButton: FBSDKLoginButton!) {
    }
}

Des idées?

19
fanfan

L'extraction FBSDKProfile n'a peut-être pas été terminée au moment du rappel de connexion. Au lieu de cela, vous pouvez observer une publication de notification 'FBSDKProfileDidChangeNotification'.

11
Chris Pan

N'oubliez pas FBSDKProfile.enableUpdatesOnAccessTokenChange(true) !! J'ai eu du mal avec cela pendant un certain temps jusqu'à ce que je trouve cela dans le docs . Ensuite, vous abonner aux notifications sur FBSDKProfileDidChangeNotification devrait fonctionner pour FBSDKLoginButton.

Exemple complet ... Je raccorde loginButton via Interface Builder

class LoginController: UIViewController, FBSDKLoginButtonDelegate {

@IBOutlet var loginButton: FBSDKLoginButton!

override func viewDidLoad() {
    super.viewDidLoad()
    loginButton.delegate = self;
    FBSDKProfile.enableUpdatesOnAccessTokenChange(true)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "onProfileUpdated:", name:FBSDKProfileDidChangeNotification, object: nil)

}

func onProfileUpdated(notification: NSNotification)
{
}

func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!){

}

func loginButtonDidLogOut(loginButton: FBSDKLoginButton!) {

}

}

27
Johnny Z

Pour ceux d'entre vous qui recherchent une réponse plus à jour et une approche plus propre que d'utiliser NSNotificationCenter, il existe une méthode de classe sur FBSDKProfile que vous pouvez appeler après la connexion qui ressemble à ceci:

[FBSDKProfile loadCurrentProfileWithCompletion:^(FBSDKProfile *profile, NSError *error) {

}];
12
Eric Alford

Je suis dans objc mais a rencontré ce problème aussi.

Tout d'abord, la réponse de Johnny Z est correcte: vous devez activer explicitement la classe FBSDKProfile en définissant 'enableUpdatesOnAccessTokenChange' sur true, puis en observant les modifications. En fait, c'est ce que FBSDKProfile fait en interne en fonction des commentaires d'en-tête.

Cependant, comme l'a noté fanfan dans un commentaire, le fichier FBSDKProfile ne contient pas tous les champs qui pourraient vous intéresser. J'ai fini par ne pas utiliser le fichier FBSDKProfile et j'ai simplement demandé à un graphique de me "ressembler",

    [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:nil]
         startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
             if (error) {
                 CLS_LOG(@"Login error: %@", [error localizedDescription]);
                 return;
             }

             NSLog(@"fecthed user: %@", result);
}];

Remarque: vous pouvez toujours observer les modifications avec la notification 'FBSDKProfileDidChangeNotification'. Lisez les commentaires de FBSDKAccessToken.h pour obtenir une documentation de cette notification et des clés à envoyer.

7
Chad Pavliska

Dans Objective-C, j'ai utilisé l'approche suivante basée sur les commentaires de ce fil.

Si cet indicateur est défini sur oui, après la connexion ou la déconnexion, une notification sera appelée. Donc, dans viewDidLoad, ajoutez cette ligne de code et ajoutez la notification à appeler après la réception du profil de l'utilisateur.

[FBSDKProfile enableUpdatesOnAccessTokenChange:YES];

[[NSNotificationCenter defaultCenter] addObserverForName:FBSDKProfileDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
     //do whatever you want
}];

Toutes les informations contenues dans ce lien https://developers.facebook.com/docs/facebook-login/ios/v2.3#profiles

6
Pedro Romão

Il semble que vous deviez appeler la méthode AppDelegate pour initialiser le SDK avant d'appeler enableUpdatesOnAccessTokenChange:YES.

J'ai fait ma méthode AppDelegate didFinishLaunching comme ceci

BOOL fbsdk = [[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions]; [FBSDKProfile enableUpdatesOnAccessTokenChange:YES]; return fbsdk;

Cela a semblé fonctionner. Vous devrez peut-être toujours faire une demande /me si vous avez besoin d'éléments ne figurant pas dans l'objet de profil.

3
Brian Broom

J'ai eu un problème similaire avec [FBSDKProfile currentProfile], mais dans Objective-C, vous pouvez également obtenir les propriétés du profil utilisateur à partir de Graph API avec la réponse à https://graph.facebook.com/me?access_token= avec votre currentAccessToken.

2
Andrei Ogrenich

Version Swift 4,

FBSDKProfile.loadCurrentProfile(completion: {
        profile, error in
        let url = profile?.imageURL(for: FBSDKProfilePictureMode.square, size:  self.imageview.frame.size)
    })
0
cnu