web-dev-qa-db-ja.com

SwiftのFacebookログインボタン

XcodeでUIViewを作成し、カスタムクラスをFBSDKLoginButtonとして追加した場合、クリックするとFacebookのログインに移動し、FBSDKLoginButtonしかし、ログインボタンを言う代わりに、今はログアウトします。ログインボタンがクリックされたときに新しいビューが表示されるようにするにはどうすればよいですか?


私はcocoapodsを介してFacebook SDKをダウンロードし、初めてそれを使用したので、これについて混乱しています。助けてくれてありがとう!

12

1つのオプションは、ビューコントローラーを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:メソッドを使用すると、resulterrorを確認できます。問題がなければ、別のビューに移動します。

スイフト

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を使用してログインする方法の詳細を確認できます。

25
veducm

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) {
    }
5
Ruud Kalis

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

デリゲートをnilに設定するために関数viewWillDissapear()を使用しないでください。Facebookログインページがアプリの上部に表示され、この関数がトリガーされます。このため、ログイン結果を取得できません。デリゲートではなくなります。 このソリューション は、ナビゲーションコントローラー内のビューで正常に機能していることに注意してください。モーダルウィンドウの別の解決策を見つける必要があります。

Xaviがお役に立てば幸いです

2
XME

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 です。

0
bLacK hoLE