简体   繁体   中英

iOS Facebook SDK 4 Session

I'm having a problem with the new FacebookSDK for iOS.

I can successfully login and get back necessary information, but when I open my app again and I intend to skip the login process, the session that I'm verifying is null.

This is my AppDelegate:

class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

    self.window!.rootViewController = LogInViewController()
    self.window!.makeKeyAndVisible()

    FBSDKProfile.enableUpdatesOnAccessTokenChange(true)
    return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}

func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {
        return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
}

func applicationDidBecomeActive(application: UIApplication) {
    FBSDKAppEvents.activateApp()
}
}

And this is my Facebook LogIn View Controller:

class LogInViewController: UIViewController, FBSDKLoginButtonDelegate {
// MARK: Properties
@IBOutlet weak var logInView: FBSDKLoginButton!

// MARK: Init
init() { super.init(nibName: "LogInViewController", bundle: nil) }
required init(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") }

// MARK: View Delegates
override func viewDidLoad() {
    super.viewDidLoad()

    if (FBSDKAccessToken.currentAccessToken() != nil) {
        // User is already logged in, do work such as go to next view controller.
        println(FBSDKAccessToken.currentAccessToken().tokenString)
        self.goToNavigation()
    } else {
        logInView.readPermissions = ["public_profile", "email", "user_friends"]
        logInView.delegate = self
    }
}

// MARK: Facebook Delegate Methods
func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!) {
    println("User Logged In")

    if ((error) != nil) {
        // Process error
    } else if result.isCancelled {
        // Handle cancellations
    } else {
        // If you ask for multiple permissions at once, you
        // should check if specific permissions missing
        if result.grantedPermissions.contains("email") {
            // Do work
            returnUserData()
        }
    }
}

func loginButtonDidLogOut(loginButton: FBSDKLoginButton!) {
    println("User Logged Out")
}

func returnUserData() {
    let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: nil)
    graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in

        if ((error) != nil) {
            // Process error
            println("Error: \(error)")
        } else {
            println("fetched user: \(result)")
            let userName : NSString = result.valueForKey("name") as! NSString
            println("User Name is: \(userName)")
            let userEmail : NSString = result.valueForKey("email") as! NSString
            println("User Email is: \(userEmail)")
        }
        self.goToNavigation()
    })
}

func goToNavigation() {
    // Creating a navigation controller with MainMenuViewController at the root of the navigation stack.
    let navController = UINavigationController(rootViewController: MainMenuViewController())
    self.presentViewController(navController, animated:true, completion: nil)
}
}

When I'm checking if (FBSDKAccessToken.currentAccessToken() != nil) I always get null for a session, although the button title is "Log out".

What could be the problem here? Any suggestions are welcome!

Answer of yourself is good. For more information you can use custom facebook button and you can call the fetch data request when the access token actually get by the login process.

Login with custom button and access token.

Get user info in facebook sdk 4.x

Swift

@IBAction func btnFBLoginPressed(sender: AnyObject) {
    var fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
    fbLoginManager .logInWithReadPermissions(["email"], handler: { (result, error) -> Void in
        if (error == nil){
            var fbloginresult : FBSDKLoginManagerLoginResult = result
            if(fbloginresult.grantedPermissions.containsObject("email"))
            {
                self.getFBUserData()
                fbLoginManager.logOut()
            }
        }
    })
}

func getFBUserData(){
    if((FBSDKAccessToken.currentAccessToken()) != nil){
        FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).startWithCompletionHandler({ (connection, result, error) -> Void in
            if (error == nil){
                println(result)
            }
        })
    }
}

Output :

{
    email = "ashishkakkad8@gmail.com";
    "first_name" = Ashish;
    id = 910855688971343;
    "last_name" = Kakkad;
    name = "Ashish Kakkad";
    picture =     {
        data =         {
            "is_silhouette" = 0;
            url = "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-xpf1/v/t1.0-1/p200x200/10394859_900936369963275_5557870055628103117_n.jpg?oh=fefbfca1272966fc78286c36741f9ac6&oe=55C89225&__gda__=1438608579_9133f15e55b594f6ac2306d61fa6b6b3";
        };
    };
}

Objective-C

Login with Facebook SDK 4.x

Add following code to facebook login button click :

FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login logInWithReadPermissions:@[@"email"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error)
 {
     if (error)
     {
         // Error
     }
     else if (result.isCancelled)
     {
         // Cancelled
     }
     else
     {
         if ([result.grantedPermissions containsObject:@"email"])
         {
             [self getFBResult];
         }
     }
}];

Get Facebook Result Method :

-(void)getFBResult
{
    if ([FBSDKAccessToken currentAccessToken])
    {
        [[[FBSDKGraphRequest alloc] initWithGraphPath:@"me" parameters:@{@"fields": @"id, name, first_name, last_name, picture.type(large), email"}]
         startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
             if (!error)
             {
                 NSLog(@"fb user info : %@",result);
             }
             else
             {
                 NSLog(@"error : %@",error);
             }
         }];   
    }
}

You can change the fields of permissions as you want.

Solved! Thanks a bunch for the suggestions, Vijay Masiwal!

Like in the suggested post, I solved the issue by using a NSNotificationCenter observer for FBSDKAccessTokenDidChangeNotification:

    override func viewDidLoad() {
    super.viewDidLoad()
    NSNotificationCenter.defaultCenter().addObserver(self, selector:"checkLogIn", name: FBSDKAccessTokenDidChangeNotification, object: nil)
}

func checkLogIn() {
    if (FBSDKAccessToken.currentAccessToken() != nil) {
        // User is already logged in, do work such as go to next view controller.
        println(FBSDKAccessToken.currentAccessToken().tokenString)
        self.goToNavigation()
    } else {
        logInView.readPermissions = ["public_profile", "email", "user_friends"]
        logInView.delegate = self
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM