在Xcode中,如果我创建UIView
然后将自定义类添加为FBSDKLoginButton
,当我点击它时会引导我浏览Facebook登录,然后将我返回到与{{1}相同的页面但不是说登录按钮,而是说现在退出。当点击登录按钮导致新视图时,我该怎么做?
我通过cocoapods下载了Facebook SDK,这是我第一次使用它,所以我对此感到困惑。谢谢你的帮助!
答案 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:
方法中,您可以查看result
和error
,如果一切正常,请导航到另一个视图。
<强>夫特强>
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。