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!
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 .
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) {
}
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
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.