关注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按钮并从那里进行自定义。我怎么能这样做?
答案 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")
}
})
}
}