Кнопка входа в Facebook для Swift

В Xcode, если я создаю UIView, а затем добавьте пользовательский класс как FBSDKLoginButton, когда я нажму, он приведет меня через вход в Facebook, а затем вернет меня на ту же страницу, что и FBSDKLoginButton, но вместо того, чтобы говорить login, он говорит, что выйдите из системы. Как я могу это сделать, когда нажата кнопка входа в систему, это приведет к новому представлению?

Я загрузил SDK для Facebook через cocoapods и его первый раз работаю с ним, поэтому я смущен этим. Спасибо за помощь!

4 ответа

Один из вариантов - установить контроллер вида в качестве делегата FBSDKLoginButton и реализовать метод loginButton:didCompleteWithResult:error:, который вызывается при использовании кнопки для входа в систему.

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

Затем в методе loginButton:didCompleteWithResult:error: вы можете проверить result и error, и если все в порядке, перейдите к другому представлению.

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

Подробнее о том, как войти в FB в своих документах, можно подробнее.


В 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 добавьте функцию разматывания:

@******** func unwindToViewOtherController(segue:UIStoryboardSegue) {
 }


В текущей версии FacebookLogin (0.2.0) для Swift свойство делегата 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)
}

... будет создан опорный цикл. В представлении будет содержаться сильная ссылка на кнопку, кнопка будет содержать сильную ссылку на контроллер, и контроллер будет иметь сильную ссылку на ее представление, см. Этот пост.

Мое решение состояло в том, чтобы использовать слабую переменную-член, чтобы иметь ссылку на кнопку входа в систему, и когда представление исчезает, делегат кнопки установлен на нуль, например:

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 *******************, 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 будет отображаться поверх вашего приложения, запуская эту функцию, и вы не получите результат входа, так как вы не будете делегата. Обратите внимание, что это решение отлично работает для просмотров внутри контроллера навигации. Другое решение должно быть найдено для модальных окон.

Надеюсь, это поможет, Хави


Вы можете сделать это как этот учебник из 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 */
- (********)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) {
 [****************** 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];
 }
 }];
 [****************** startAnimating]; // Show loading indicator until login is finished
}

Ниже приведено демо-приложение.

licensed under cc by-sa 3.0 with attribution.