Facebook Login button for Swift

眉间皱痕 提交于 2019-12-20 09:42:47

问题


In Xcode if I create a UIView and then add the custom class as FBSDKLoginButton, when I click it leads me through the Facebook login and then returns me to the same page as the FBSDKLoginButton but instead of saying login button it says log out now. How would I go about making that when the login button is clicked it lead to a new view?


I downloaded the Facebook SDK through cocoapods and its my first time working with it so I am confused about this. Thanks for the help!


回答1:


One option would be to set your view controller as a delegate of the FBSDKLoginButton and implement the loginButton:didCompleteWithResult:error: method, which is called when the button is used to login.

Swift

class ViewController: UIViewController, FBSDKLoginButtonDelegate {

    @IBOutlet weak var loginButton: FBSDKLoginButton!        

    override func viewDidLoad() {
        super.viewDidLoad()

        self.loginButton.delegate = self
    }
}

Obj-C

// ViewController.h
@interface ViewController : UIViewController <FBSDKLoginButtonDelegate>

@property (weak, nonatomic) IBOutlet FBSDKLoginButton *loginButton;

@end

// ViewController.m
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.loginButton.delegate = self;
}

Then, in the loginButton:didCompleteWithResult:error: method you can check the result and error, and if everything is fine, navigate to another view.

Swift

func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!) {
        if ((error) != nil) {
            // Process error
        }
        else if result.isCancelled {
            // Handle cancellations
        }
        else {
            // Navigate to other view
        }   
    }

Obj-C

// ViewController.m
@implementation ViewController

- (void)loginButton:(FBSDKLoginButton *)loginButton 
  didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result
                  error:(NSError *)error {
    if (error) {
        // Process error
    }
    else if (result.isCancelled) {
       // Handle cancellations
    }
    else {
        // Navigate to other view
    }
}

You can find more about how to login with FB in their docs.




回答2:


In Swift that would be something like:

class MyViewController: UIViewController, FBSDKLoginButtonDelegate {
    @IBOutlet weak var loginView : FBSDKLoginButton!
    @IBOutlet weak var profilePictureView : FBSDKProfilePictureView!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.loginView.delegate = self

        if (FBSDKAccessToken.currentAccessToken() != nil)
        {
            performSegueWithIdentifier("unwindToViewOtherController", sender: self) 
        }
        else
        {
            loginView.readPermissions = ["public_profile", "email", "user_friends"]
        }

    }

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

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

Then in your TargetViewController add an unwind function:

@IBAction func unwindToViewOtherController(segue:UIStoryboardSegue) {
    }



回答3:


In current FacebookLogin version (0.2.0) for Swift, the LoginButton delegate property is defined as a strong property:

public class LoginButton: UIView {
...
  /// Delegate of the login button that can handle the result, logout events.
public var delegate: LoginButtonDelegate?
... }

If you add the login button following Facebook instructions and you set your UIViewController child class as button delegate...

import FacebookLogin

func viewDidLoad() {
    let loginButton = LoginButton(readPermissions: [ .PublicProfile ])
    loginButton.center = view.center
    loginButton.delegate = self
    view.addSubview(loginButton)
}

... a reference cycle will be created. The view will contain a strong reference to the button, the button will contain a strong reference to the controller, and the controller will have a strong reference to its view, see this post.

My solution was to use a weak member variable to have a reference to the login button and when the view disappears, the button delegate is set to nil, like this:

import UIKit
import FacebookCore
import FacebookLogin
import RxSwift

class LoginViewController: UIViewController, LoginButtonDelegate {

    private weak var facebookLoginButton: LoginButton? = nil

    override func viewDidLoad() {

        super.viewDidLoad()

        // Add the Facebook login button
        let loginButton = LoginButton(readPermissions: [ .publicProfile, .email, .userFriends ])
        loginButton.center = view.center
        // WARNING!: Facebook login button delegate property is defined currently as STRONG.
        // Therefore, it must be set to nil before leaving the view to avoid reference cycles
        loginButton.delegate = self
        view.addSubview(loginButton)
        // Store the login button as a weak reference, since it is holded by the main view with a
        // strong reference
        facebookLoginButton = loginButton
    }

    override func willMove(toParentViewController parent: UIViewController?) {
        super.willMove(toParentViewController:parent)
        if parent == nil {
            // The back button was pressed, interactive gesture used, or programatically pop view
            // was executed
            // Do not forget to set delegate in Facebook button to nil to break reference cycle.
            facebookLoginButton?.delegate = nil
        }
    }

    // MARK: - Facebook login

    /**
     Called when the button was used to login and the process finished.

     - parameter loginButton: Button that was used to login.
     - parameter result:      The result of the login.
     */
    func loginButtonDidCompleteLogin(_ loginButton: LoginButton, result: LoginResult) {

        switch result {
            case .failed(let error):
                // Action on failed
            case .cancelled:
                // Action on cancelled
            case .success(let grantedPermissions, let declinedPermissions, let accessToken):
                // Action on success
        }
    }

    /**
     Called when the button was used to logout.

     - parameter loginButton: Button that was used to logout.
     */
    func loginButtonDidLogOut(_ loginButton: LoginButton) {

        // Action on logout
    }
}

Do not use function viewWillDissapear() for setting to nil the delegate, because Facebook login page will be shown on top of your app, triggering this function, and you will not get the login result since you will not be the delegate anymore. Note that this solution is working fine for views inside a navigation controller. Another solution should be found for modal windows.

I hope it helps, Xavi




回答4:


You could do this like this tutorial from appcoda (see code below)

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"Facebook Profile";

    // Check if user is cached and linked to Facebook, if so, bypass login    
    if ([PFUser currentUser] && [PFFacebookUtils isLinkedWithUser:[PFUser currentUser]]) {
        [self.navigationController pushViewController:  [[UserDetailsViewController alloc] initWithStyle:UITableViewStyleGrouped] animated:NO];
    }

}


#pragma mark - Login methods

/* Login to facebook method */

- (IBAction)loginButtonTouchHandler:(id)sender  {
    // Set permissions required from the facebook user account
    NSArray *permissionsArray = @[ @"user_about_me", @"user_relationships", @"user_birthday", @"user_location"];

// Login PFUser using facebook
[PFFacebookUtils logInWithPermissions:permissionsArray block:^(PFUser *user, NSError *error) {
    [_activityIndicator stopAnimating]; // Hide loading indicator

    if (!user) {
        if (!error) {
            NSLog(@"Uh oh. The user cancelled the Facebook login.");
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Log In Error" message:@"Uh oh. The user cancelled the Facebook login." delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Dismiss", nil];
            [alert show];
        } else {
            NSLog(@"Uh oh. An error occurred: %@", error);
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Log In Error" message:[error description] delegate:nil cancelButtonTitle:nil otherButtonTitles:@"Dismiss", nil];
            [alert show];
        }
    } else if (user.isNew) {
        NSLog(@"User with facebook signed up and logged in!");
        [self.navigationController pushViewController:[[UserDetailsViewController alloc] initWithStyle:UITableViewStyleGrouped] animated:YES];
    } else {
        NSLog(@"User with facebook logged in!");
        [self.navigationController pushViewController:[[UserDetailsViewController alloc] initWithStyle:UITableViewStyleGrouped] animated:YES];
         }
    }];

    [_activityIndicator startAnimating]; // Show loading indicator until login is finished
}

Here is a demo app for this.



来源:https://stackoverflow.com/questions/29750047/facebook-login-button-for-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!