FacebookSDK(4.1.x) Custom Login UI Button - Swift(1.2)

前端 未结 6 2032
挽巷
挽巷 2020-12-05 12:28

Following this tutorial, I have managed to make a Facebook Login Button working. However, it is assigning the button image automatically from the SDK and it is not customisa

相关标签:
6条回答
  • 2020-12-05 12:47

    Reusable class (Swift 4).

    Usage: 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
    }
    
    0 讨论(0)
  • 2020-12-05 12:47

    As of June 2017, the accepted answer updated for Swift 3 and latest version of FBSDK, the code looks like below-

    @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")
                    }
                })
            }
        }
    
    0 讨论(0)
  • 2020-12-05 12:48

    Login with custom button and access token.

    Get user info in facebook sdk 4.x

    Swift

    @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)
                }
            })
        }
    }
    
    0 讨论(0)
  • 2020-12-05 13:00

    I did it successfully in 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)
                }
            })
        }
    }
    
    0 讨论(0)
  • 2020-12-05 13:06

    Updated answer using the last Facebook SDK (01/05/2016) and Swift 2.1

    Create a UIButton with Interface Builder or by code and link the action of that button with this:

    @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()
                }
            }
        }
    }
    

    The happy case of the previous code triggers the function self.getFBUserData() so you have to implement that function in the same file

    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)
                }
            })
        }
    }
    
    0 讨论(0)
  • 2020-12-05 13:08

    If you want to use the native button try this out:

    let buttonText = NSAttributedString(string: "your text here")
    facebookButton.setAttributedTitle(buttonText, for: .normal)
    
    0 讨论(0)
提交回复
热议问题