FacebookSDK(4.1.x)自定义登录UI按钮 - Swift(1.2)

时间:2015-06-04 03:05:36

标签: ios facebook swift

关注this tutorial,我设法让Facebook登录按钮正常工作。但是,它会自动从SDK中分配按钮图像,并且不能自定义(因为它没有在Storyboard上创建),所以我无法使用自己的按钮图像或文本。

我相信这部分代码(在ViewDidLoad中)是分配按钮:

        let loginView : FBSDKLoginButton = FBSDKLoginButton()
        self.view.addSubview(loginView)
        loginView.center = self.view.center
        loginView.readPermissions = ["public_profile", "email"]
        loginView.delegate = self

我需要做的是在Storyboard上创建一个@IBOutlet按钮并从那里进行自定义。我怎么能这样做?

6 个答案:

答案 0 :(得分:34)

使用自定义按钮和访问令牌登录。

在facebook sdk 4.x中获取用户信息

夫特

@IBAction func btnFBLoginPressed(sender: AnyObject) {
    var fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
    fbLoginManager.logInWithReadPermissions(["email"], fromViewController: self, handler: { (result, error) -> Void in
        if (error == nil){
            var fbloginresult : FBSDKLoginManagerLoginResult = result
            if(fbloginresult.grantedPermissions.contains("email"))
            {
                self.getFBUserData()
                fbLoginManager.logOut()
            }
        }
    })
}

func getFBUserData(){
    if((FBSDKAccessToken.currentAccessToken()) != nil){
        FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).startWithCompletionHandler({ (connection, result, error) -> Void in
            if (error == nil){
                println(result)
            }
        })
    }
}

答案 1 :(得分:7)

使用上一个Facebook SDK(2016年5月1日)和Swift 2.1

更新了答案

使用Interface Builder或代码创建UIButton,并将该按钮的操作链接到:

@IBAction func loginFacebookAction(sender: AnyObject) {
    let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
    fbLoginManager.logInWithReadPermissions(["email"], fromViewController: self) { (result, error) -> Void in
        if (error == nil){
            let fbloginresult : FBSDKLoginManagerLoginResult = result
            if(fbloginresult.grantedPermissions.contains("email"))
            {
                self.getFBUserData()
            }
        }
    }
}

上一个代码的幸福案例触发函数self.getFBUserData(),因此您必须在同一个文件中实现该函数

func getFBUserData(){
    if((FBSDKAccessToken.currentAccessToken()) != nil){
        FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).startWithCompletionHandler({ (connection, result, error) -> Void in
            if (error == nil){
                //everything works print the user data
                print(result)
            }
        })
    }
}

答案 2 :(得分:2)

我在xcode 7.3中成功完成了

    @IBAction func fbLoginBtnAction(sender: AnyObject) {

    let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()

    fbLoginManager.logInWithReadPermissions(["email"], fromViewController: self, handler: {(result, error) -> Void in
            if error == nil {
                print("Logged in through facebook" )
                self.getFBUserData()
            }
            else {
                print("Facebook Login Error----\n",error)
            }
        }
    )
}


  func getFBUserData () {
    if((FBSDKAccessToken.currentAccessToken()) != nil){
        FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).startWithCompletionHandler({ (connection, result, error) -> Void in
            if (error == nil){
                print(result)
            }
        })
    }
}

答案 3 :(得分:1)

可重复使用的课程(Swift 4)。

用法:FacebookSignIn.shared.signIn(from: yourVC, completion: yourCompletion)

class FacebookSignIn {

   enum Error: Swift.Error {
      case unableToInitializeGraphRequest
      case unexpectedGraphResponse
      case permissionsIsNotGranted
      case unexpectedLoginResponse
      case canceled
   }

   struct Permissions {

      static let email = "email"
      static let profile = "public_profile"

      static func isValidPermissions(_ permissions: Set<AnyHashable>) -> Bool {
         return permissions.contains(email) && permissions.contains(profile)
      }

      static var permissions: [String] {
         return [email, profile]
      }
   }

   public static let shared = FacebookSignIn()

   private init() {
   }

}

extension FacebookSignIn {

   func signIn(from: UIViewController, completion: Result<SignInResponse>.Completion?) {
      let manager = FBSDKLoginManager()
      manager.loginBehavior = .native
      if !isValidToken {
         manager.logOut()
      }
      if let token = FBSDKAccessToken.current() {
         let interval = token.expirationDate.timeIntervalSince(Date())
         if interval > 300 { // At least 5 min token will be valid
            performLogin {
               switch $0 {
               case .failure(let error):
                  completion?(.failure(error))
               case .success(let info):
                  completion?(.success(SignInResponse(accessToken: token.tokenString, userInfo: info)))
               }
            }
         } else {
            FBSDKAccessToken.refreshCurrentAccessToken { [weak self] _, _, error in
               if let error = error {
                  manager.logOut()
                  completion?(.failure(error))
               } else {
                  let token = FBSDKAccessToken.current()?.tokenString ?? "" // Should be always valid value at this point.
                  self?.performLogin {
                     switch $0 {
                     case .failure(let error):
                        completion?(.failure(error))
                     case .success(let info):
                        completion?(.success(SignInResponse(accessToken: token, userInfo: info)))
                     }
                  }
               }
            }
         }
      } else {
         manager.logIn(withReadPermissions: Permissions.permissions, from: from) { [weak self] result, error in
            if let error = error {
               manager.logOut()
               completion?(.failure(error))
               return
            }
            guard let result = result else {
               manager.logOut()
               completion?(.failure(Error.unexpectedLoginResponse))
               return
            }
            let permissions = result.grantedPermissions ?? Set<AnyHashable>()
            let token = result.token?.tokenString ?? "" // Should be always valid value at this point.
            if result.isCancelled {
               manager.logOut()
               completion?(.failure(Error.canceled))
            } else if Permissions.isValidPermissions(permissions) {
               self?.performLogin {
                  switch $0 {
                  case .failure(let error):
                     completion?(.failure(error))
                  case .success(let info):
                     completion?(.success(SignInResponse(accessToken: token, userInfo: info)))
                  }
               }
            } else {
               manager.logOut()
               completion?(.failure(Error.permissionsIsNotGranted))
            }
         }
      }
   }

   private var isValidToken: Bool {
      guard let token = FBSDKAccessToken.current() else {
         return false
      }
      return Permissions.isValidPermissions(token.permissions ?? Set<AnyHashable>())
   }

   private func makeGraphRequest() -> FBSDKGraphRequest? {
      guard FBSDKAccessToken.current().tokenString != nil else {
         return nil
      }
      // You might not get email: https://developers.facebook.com/docs/facebook-login/permissions/v2.4
      // Note, even if you request the email permission it is not guaranteed you will get an email address. For example,
      // if someone signed up for Facebook with a phone number instead of an email address, the email field may be empty.
      let fields = "email,id,first_name,last_name,gender"
      return FBSDKGraphRequest(graphPath: "me", parameters: ["fields": fields])
   }

   private func performLogin(completion: Result<[String: String]>.Completion?) {
      let manager = FBSDKLoginManager()
      guard let request = makeGraphRequest() else {
         manager.logOut()
         completion?(.failure(Error.unableToInitializeGraphRequest))
         return
      }
      _ = request.start { _, result, error in
         if let e = error {
            manager.logOut()
            completion?(.failure(e))
         } else if let result = result as? [String: String] {
            completion?(.success((result)))
         } else {
            manager.logOut()
            completion?(.failure(Error.unexpectedGraphResponse))
         }
      }
   }

}
public struct SignInResponse {

   public let accessToken: String
   public let userInfo: [String: String]

   public init(accessToken: String, userInfo: [String: String]) {
      self.accessToken = accessToken
      self.userInfo = userInfo
   }
}


public enum Result<T> {

   case success(T)
   case failure(Swift.Error)

   public typealias Completion = (Result<T>) -> Void
}

答案 4 :(得分:0)

如果你想使用原生按钮试试这个:

let buttonText = NSAttributedString(string: "your text here")
facebookButton.setAttributedTitle(buttonText, for: .normal)

答案 5 :(得分:0)

截至2017年6月,为Swift 3和最新版本的FBSDK更新了已接受的答案,代码如下所示 -

@IBAction func fbLoginPressed(_ sender: Any) {
        let fbLoginManager: FBSDKLoginManager = FBSDKLoginManager()

        fbLoginManager.logIn(withReadPermissions: ["email"], from: self) { (result, error) in
            if error == nil {
                if let fbLoginResult = result {
                    if fbLoginResult.grantedPermissions != nil && fbLoginResult.grantedPermissions.contains("email"){
                        self.getFBUserdata()
                    }
                }
            }
        }
    }

    func getFBUserdata(){
        if FBSDKAccessToken.current() != nil{
            FBSDKGraphRequest(graphPath: "me", parameters: ["fields":"id,name,first_name, last_name, picture.type(large), email"]).start(completionHandler: { (cnnection, result, error) in
                if error == nil{
                    print(result ?? "Error in getFBUserdata function")
                }
            })
        }
    }