XcodeでUIView
を作成し、カスタムクラスをFBSDKLoginButton
として追加した場合、クリックするとFacebookのログインに移動し、FBSDKLoginButton
しかし、ログインボタンを言う代わりに、今はログアウトします。ログインボタンがクリックされたときに新しいビューが表示されるようにするにはどうすればよいですか?
私はcocoapodsを介してFacebook SDKをダウンロードし、初めてそれを使用したので、これについて混乱しています。助けてくれてありがとう!
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:
メソッドを使用すると、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を使用してログインする方法の詳細を確認できます。
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) {
}
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がお役に立てば幸いです
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 です。