Swift的Facebook登录按钮

时间:2015-04-20 14:00:58

标签: ios facebook swift facebook-login

在Xcode中,如果我创建UIView然后将自定义类添加为FBSDKLoginButton,当我点击它时会引导我浏览Facebook登录,然后将我返回到与{{1}相同的页面但不是说登录按钮,而是说现在退出。当点击登录按钮导致新视图时,我该怎么做?


我通过cocoapods下载了Facebook SDK,这是我第一次使用它,所以我对此感到困惑。谢谢你的帮助!

5 个答案:

答案 0 :(得分:24)

一种选择是将视图控制器设置为FBSDKLoginButton的委托,并实现loginButton:didCompleteWithResult:error:方法,该方法在使用按钮登录时调用。

<强>夫特

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

然后,在loginButton:didCompleteWithResult:error:方法中,您可以查看resulterror,如果一切正常,请导航到另一个视图。

<强>夫特

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

您可以在their docs中找到有关如何使用FB登录的详情。

答案 1 :(得分:5)

在Swift中会出现类似的情况:

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

然后在TargetViewController中添加一个展开函数:

@IBAction func unwindToViewOtherController(segue:UIStoryboardSegue) {
    }

答案 2 :(得分:2)

在Swift的当前FacebookLogin版本(0.2.0)中,LoginButton委托属性被定义为强属性:

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

如果您按照Facebook说明添加登录按钮,并将UIViewController子类设置为按钮代理...

import FacebookLogin

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

...将创建一个参考周期。该视图将包含对该按钮的强引用,该按钮将包含对控制器的强引用,并且控制器将具有对其视图的强引用,请参阅此post

我的解决方案是使用弱成员变量来引用登录按钮,当视图消失时,按钮委托设置为nil,如下所示:

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

不要使用函数viewWillDissapear()设置为nil代理,因为Facebook登录页面将显示在您的应用程序顶部,触发此功能,您将无法获得登录结果,因为您将不再是代表。请注意this solution适用于导航控制器内的视图。应该为模态窗口找到另一种解决方案。

我希望它有所帮助, 哈维

答案 3 :(得分:2)

IOS 13使用场景委托。只需将以下代码粘贴到场景委托中,然后简单地调用facebook登录管理器,它将返回facebook的用户对象。此功能会自动调用。

 func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        guard let url = URLContexts.first?.url else {
            return
        }
        let _ = ApplicationDelegate.shared.application(
            UIApplication.shared,
            open: url,
            sourceApplication: nil,
            annotation: [UIApplication.OpenURLOptionsKey.annotation])
    }

答案 4 :(得分:0)

您可以像appcoda中的本教程那样执行此操作(请参阅下面的代码)

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

这是demo app