Facebook Login Button for Swift

In Xcode, if I create a UIView , then add a custom class as FBSDKLoginButton , when I click, it will lead me through the Facebook login and then bring me back to the same page as FBSDKLoginButton , but instead of saying login, it says log out. How can I do this when the login button is pressed, it will lead to a new view?


I downloaded the Facebook SDK via cocoapods and its first time working with it, so I'm confused about this. Thanks for the help!

+8
ios facebook swift facebook-login
source share
4 answers

One option is to set the view controller as a FBSDKLoginButton delegate and implement the loginButton:didCompleteWithResult:error: method, which is called when the button is used to enter the system.

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 ok, go 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 read more about how to enter FB in your documents .

+20
source share

In Swift, it will 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
source share

In the current version of FacebookLogin (0.2.0) for Swift, the delegate property of LoginButton 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 the instructions of Facebook and you set the child class of the UIViewController as the delegate of the button ...

 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 link to the button, the button will contain a strong link to the controller, and the controller will have a strong link to its view, see this post .

My solution was to use a weak member variable to have a link to the login button, and when the view disappears, the button delegate is set to zero, for example:

 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 the viewWillDissapear() function to set the delegate to nil , because the Facebook login page will be displayed on top of your application, running this function, and you will not get the login result, since you will not be a delegate. Note that this solution works great for views inside the navigation controller. Another solution should be found for modal windows.

Hope this helps, Xavi

+2
source share

You can do it 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 } 

Below is a demo application .

0
source share

All Articles