web-dev-qa-db-fra.com

Bouton de connexion Facebook pour Swift

Dans Xcode si je crée un UIView puis que j'ajoute la classe personnalisée en tant que FBSDKLoginButton, lorsque je clique dessus, il me conduit à travers la connexion Facebook et me renvoie ensuite à la même page que le FBSDKLoginButton mais au lieu de dire bouton de connexion, il est dit de se déconnecter maintenant. Comment pourrais-je faire cela lorsque le bouton de connexion est cliqué, cela conduirait à une nouvelle vue?


J'ai téléchargé le SDK Facebook via des cocoapods et c'est la première fois que je travaille avec, donc je suis confus à ce sujet. Merci pour l'aide!

12
Soporificdreamer

Une option serait de définir votre contrôleur de vue en tant que délégué de FBSDKLoginButton et d'implémenter loginButton:didCompleteWithResult:error: , qui est appelée lorsque le bouton est utilisé pour se connecter.

Rapide

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

Ensuite, dans le loginButton:didCompleteWithResult:error: vous pouvez vérifier les result et error, et si tout va bien, accédez à une autre vue.

Rapide

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

Vous pouvez trouver plus d'informations sur la connexion avec FB dans leurs documents .

25
veducm

Dans Swift ce serait quelque chose comme:

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

Ensuite, dans votre TargetViewController, ajoutez une fonction de déroulement:

@IBAction func unwindToViewOtherController(segue:UIStoryboardSegue) {
    }
5
Ruud Kalis

Dans la version actuelle de FacebookLogin (0.2.0) pour Swift, la propriété déléguée LoginButton est définie comme une propriété forte:

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

Si vous ajoutez le bouton de connexion en suivant les instructions de Facebook et que vous définissez votre classe enfant UIViewController en tant que délégué de bouton ...

import FacebookLogin

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

... un cycle de référence sera créé. La vue contiendra une référence forte au bouton, le bouton contiendra une référence forte au contrôleur, et le contrôleur aura une référence forte à sa vue, voir ceci post .

Ma solution était d'utiliser une variable de membre faible pour avoir une référence au bouton de connexion et lorsque la vue disparaît, le délégué de bouton est défini sur zéro, comme ceci:

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

N'utilisez pas la fonction viewWillDissapear() pour définir sur nil le délégué, car la page de connexion Facebook s'affichera au-dessus de votre application, déclenchant cette fonction, et vous n'obtiendrez pas le résultat de la connexion puisque vous ne sera plus le délégué. Notez que cette solution fonctionne bien pour les vues à l'intérieur d'un contrôleur de navigation. Une autre solution devrait être trouvée pour les fenêtres modales.

J'espère que ça aide, Xavi

2
XME

Vous pouvez le faire comme ce tutoriel de appcoda (voir le code ci-dessous)

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

Voici un application de démonstration pour cela.

0
bLacK hoLE