ios Swift 的 Facebook 登录按钮
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29750047/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Facebook Login button for Swift
提问by Soporificdreamer
In Xcode if I create a UIView
and then add the custom class as FBSDKLoginButton
, when I click it leads me through the Facebook login and then returns me to the same page as the FBSDKLoginButton
but instead of saying login button it says log out now. How would I go about making that when the login button is clicked it lead to a new view?
在 Xcode 中,如果我创建一个UIView
,然后将自定义类添加为FBSDKLoginButton
,当我单击它时,它会引导我完成 Facebook 登录,然后将我返回到与 相同的页面,FBSDKLoginButton
但不是说登录按钮,而是说现在注销。当单击登录按钮时,我将如何进行它导致一个新视图?
I downloaded the Facebook SDK through cocoapods and its my first time working with it so I am confused about this. Thanks for the help!
我通过 cocoapods 下载了 Facebook SDK,这是我第一次使用它,所以我对此感到困惑。谢谢您的帮助!
回答by veducm
One option would be to set your view controller as a delegate of the FBSDKLoginButton
and implement the loginButton:didCompleteWithResult:error:
method, which is called when the button is used to login.
一种选择是将您的视图控制器设置为 的委托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
对象-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 fine, navigate to another view.
然后,在该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
对象-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 find more about how to login with FB in their docs.
您可以在他们的文档中找到有关如何使用 FB 登录的更多信息。
回答by Ruud Kalis
In Swift that would be something like:
在 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")
}
}
Then in your TargetViewController add an unwind function:
然后在你的 TargetViewController 添加一个 unwind 函数:
@IBAction func unwindToViewOtherController(segue:UIStoryboardSegue) {
}
回答by XME
In current FacebookLogin version (0.2.0) for Swift, the LoginButton delegate property is defined as a strong property:
在 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?
... }
If you add the login button following Facebook instructions and you set your UIViewController
child class as button delegate...
如果您按照 Facebook 说明添加登录按钮,并将您的UIViewController
子类设置为按钮委托...
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 reference to the button, the button will contain a strong reference to the controller, and the controller will have a strong reference to its view, see this post.
... 将创建一个参考循环。视图将包含对按钮的强引用,按钮将包含对控制器的强引用,而控制器将对其视图具有强引用,请参阅此帖子。
My solution was to use a weak member variable to have a reference to the login button and when the view disappears, the button delegate is set to nil, like this:
我的解决方案是使用弱成员变量来引用登录按钮,当视图消失时,按钮委托设置为 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
}
}
Do not use function viewWillDissapear()
for setting to nil
the delegate, because Facebook login page will be shown on top of your app, triggering this function, and you will not get the login result since you will not be the delegate anymore. Note that this solutionis working fine for views inside a navigation controller. Another solution should be found for modal windows.
请勿使用函数viewWillDissapear()
设置nil
委托,因为 Facebook 登录页面将显示在您的应用程序顶部,触发此功能,您将无法获得登录结果,因为您不再是委托人。请注意,此解决方案适用于导航控制器内的视图。应该为模态窗口找到另一个解决方案。
I hope it helps, Xavi
我希望它有帮助,哈维
回答by Talha Rasool
IOS 13 use Scene Delegate. Just paste the below code in scene delegate and simple call the facebook login manager it will return the user object of facebook. This function automatically call.
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])
}
回答by bLacK hoLE
You could do this like this tutorial from appcoda(see code below)
您可以从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
}
Here is a demo appfor this.
这是一个演示应用程序。