Customized Facebook Login Button - After integration - ios

I am trying to customize the Facebook login button after following this guide. Everything is integrated correctly, I can login to Facebook, and logout without a hitch.
Now my next goal is to make the screen look like my mock up, this includes placing the login button correctly on the storyboard, but the only issue is that it doesn't show up on the story board, it just appears when I run the simulation. I looked at other overflow answers, but they weren't really helpful as they were geared towards earlier versions of swift / Xcode, and didn't work from what the comments said. My code is exactly the same as the guide, as this is the first screen that I am trying to implement.
Help would be much appreciated.

If you want to use the custom facebook SDK button you can create any custom button in the storyboard and provide action in the viewcontroller like this
Import at top
import FBSDKCoreKit
import FBSDKLoginKit
Swift 3:
#IBAction func loginFacebookAction(sender: AnyObject) {//action of the custom button in the storyboard
let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
fbLoginManager.logIn(withReadPermissions: ["email"], from: self) { (result, error) -> Void in
if (error == nil){
let fbloginresult : FBSDKLoginManagerLoginResult = result!
// if user cancel the login
if (result?.isCancelled)!{
return
}
if(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: { (connection, result, error) -> Void in
if (error == nil){
//everything works print the user data
print(result)
}
})
}
}
Older Swift version:
#IBAction func loginFacebookAction(sender: AnyObject) {//action of the custom button in the storyboard
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()
}
}
}
}
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)
}
})
}
}
If you want default facebook login button you can take UIView and set Class* field of the Custom Class** section in the Identity Inspector, we must set the FBLoginValue
Ref: Default SDK login button tutorial:http://www.appcoda.com/ios-programming-facebook-login-sdk/
Ref: Custom SDK login button for parameters and more info:https://developers.facebook.com/docs/facebook-login/ios

POD INSTALL
source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
target “ProjectName” do
pod 'FacebookCore'
pod 'FacebookLogin'
pod 'FacebookShare'
end
AppDelegate.swift
import FacebookLogin
import FBSDKLoginKit
import FacebookCore
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
return true
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
}
ViewController.swift
import UIKit
import FacebookLogin
import FBSDKLoginKit
import FacebookCore
class ViewController: UIViewController {
override func viewDidLoad() {
if(FBSDKAccessToken.current() == nil){
print("Not logged in ")
}else{
print("Logged in already")
getFacebookUserInfo()
}
}
#IBAction func CustomButton_Click(_ sender: Any) {
getFacebookUserInfo()
}
func getFacebookUserInfo(){
let loginManager = LoginManager()
loginManager.logIn([.publicProfile, .email ], viewController: self) { (result) in
switch result{
case .cancelled:
print("Cancel button click")
case .success:
let params = ["fields" : "id, name, first_name, last_name, picture.type(large), email "]
let graphRequest = FBSDKGraphRequest.init(graphPath: "/me", parameters: params)
let Connection = FBSDKGraphRequestConnection()
Connection.add(graphRequest) { (Connection, result, error) in
let info = result as! [String : AnyObject]
print(info["name"] as! String)
}
Connection.start()
default:
print("??")
}
}
}
}
Info.plist
Info.plist --> right click ->OpenAs -->Source Code --> add < dict > .. < /dict >
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>YOUR APP ID</string>
</array>
</dict>
</array>
<key>FacebookAppID</key>
<string>YOUR APP ID</string>
<key>FacebookDisplayName</key>
<string>YOUR APP NAME</string>

#IBAction func buttonLogin(_ sender: Any) {
let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
fbLoginManager.logIn(withReadPermissions: ["public_profile","email"], from: self) { (result, error) in
if (error == nil){
let fbloginresult : FBSDKLoginManagerLoginResult = result!
if fbloginresult.grantedPermissions != nil {
if(fbloginresult.grantedPermissions.contains("email")) {
if((FBSDKAccessToken.current()) != nil){
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).start(completionHandler: { (connection, result, error) -> Void in
if (error == nil){
let dict: NSDictionary = result as! NSDictionary
if let token = FBSDKAccessToken.current().tokenString {
print("tocken: \(token)")
let userDefult = UserDefaults.standard
userDefult.setValue(token, forKey: "access_tocken")
userDefult.synchronize()
}
if let user : NSString = dict.object(forKey:"name") as! NSString? {
print("user: \(user)")
}
if let id : NSString = dict.object(forKey:"id") as? NSString {
print("id: \(id)")
}
if let email : NSString = (result! as AnyObject).value(forKey: "email") as? NSString {
print("email: \(email)")
}
}
})
}
}
}
}
}
}

Welcome to StackOverflow, Shika! That tutorial shows you how to add the button that Facebook provides as part of their SDK. The tutorial tells you centers the button in the center of the device's screen. Facebook allows you to create your own button, if you'd like to. In my opinion, I like it better, because you can play with it in the storyboard, unlike the button created programmatically in Swift. You can use the Facebook docs here and scroll down to "Custom Login Button". Your code will change, but not by much! If you choose to go this route, make sure to delete the code you copied and pasted to add the button located in viewDidLoad. Also, you can delete the FBSDKLoginButtonDelegate you added at the top of the Swift file.

Related

Facebook login not dismissing the webpage.

I am using a custom button for my Facebook login. When I click the button a webpage inside the app opens the facebook page with login with app or email/phone. I click open in app, and go through the process. After that process, I get redirected to my app, but the webpage still appears, and is not dismiss.
#IBAction func loginFacebookAction(sender: AnyObject) {//action of the custom button in the storyboard
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()
}
}
}
}
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)
}
})
}
}

logging into fb from iOS app

I am using the below methods to login to fb through my app. It is successfully navigating to login page but printing an error as follows:
**-canOpenURL: failed for URL: "fbauth2:/" - error: "(null)"
** using swift 2.1.1 and facebook sdk 4.13.1
let fbLoginManager = FBSDKLoginManager()
fbLoginManager.logInWithReadPermissions(["email"], fromViewController: self) { (result, error) -> Void in
if (error == nil){
let fbloginresult : FBSDKLoginManagerLoginResult = result
if fbloginresult.grantedPermissions != nil && 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, gender"]).startWithCompletionHandler({ (connection, result, error) -> Void in
if (error == nil){
print(result)
let view = self.storyboard?.instantiateViewControllerWithIdentifier("View") as! SignupViewController
self.presentViewController(View, animated: true, completion: nil)
}
})
}
}
Using
<key>LSApplicationQueriesSchemes</key>
<array>
<string>fbapi</string>
<string>fb-messenger-api</string>
<string>fbauth2</string>
<string>fbshareextension</string>
</array>
Also when I am redirecting to View, it goes to loginview and then going to redirected View.can anyone help me...

Facebook SDK and Swift 2.0 - Problems with handling accessToken

my name is Vincent and I need your help !
(My code is not exhaustive)
No problem to login or logout with the Facebook SDK ... BUT
When I start my app, no access token and when i click on the Login button, it prints me an accessToken, then I logout.
How to get the accessToken when the app starts ?
import UIKit
import FBSDKCoreKit
import FBSDKLoginKit
class HomeViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
getUserStatuts()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK -> Facebook Connect
func loginToFacebook() {
if let fbToken = FBSDKAccessToken.currentAccessToken() {
print("Acces token : \(fbToken)")
loginManager.logOut()
print("Logout")
} else {
print("Login")
loginManager.logInWithPublishPermissions(publishPermissions, fromViewController: nil, handler: {
(result:FBSDKLoginManagerLoginResult!, error:NSError!) -> Void in
if error == nil {
self.getUserData()
} else {
print(error.localizedDescription)
}
})
}
}
func getUserData() {
let readPermissions = ["public_profile", "email", "user_friends", "user_birthday"]
let parameters = ["fields": "id, first_name, last_name, name, birthday, picture.type(large)"]
let request = FBSDKGraphRequest(graphPath: "me", parameters: parameters)
request.startWithCompletionHandler({
(connection, result, error) -> Void in
if error == nil {
// display info
}
})
}
In the login function you want to implement the
let fbLogin = FBSDKLoginManager()
fblogin.logout()
the fblogin.logout() must be implemented before fbLogin.logInWithReadPermissions(["email"], fromViewController: self) { (facebookResult, facebookError) in
if facebookError != nil { ` to clear any access tokens from previous login.

How to make a login flow IOS app

I made a login trough the facebook in my app using the Facebook SDK. Basically I have a login screen that when the user clicks in "Facebook" button it make whole auth routine (open the safari and ask for accept the permission). When the user is not logged after accept the access to app it goes to another view (Main screen of app).
The problem is when the user is already logged... I would like open the app in main screen without display login view.
I'm verifying if user is logger in LoginController at viewDidAppear and calling performSegueWithIdentifier method because in viewDidLoad it doesn't work.
Which is the best way to make a login screen?
class LoginViewController: UIViewController{
let defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
override func viewDidLoad() {
}
override func viewDidAppear(animated: Bool) {
print("Will Appear method")
if (self.defaults.stringForKey("isLogged") != nil){
self.performSegueWithIdentifier("facebookLoginSegue", sender: nil)
}
}
//MARK - Actions
#IBAction func facebookLogin(sender: UIButton) {
FBSDKLoginManager().logInWithReadPermissions(["public_profile", "email", "user_friends"], fromViewController:self, handler: { (result:FBSDKLoginManagerLoginResult!, error:NSError!) -> Void in
if (error == nil){
let fbloginresult : FBSDKLoginManagerLoginResult = result
if(fbloginresult.grantedPermissions.contains("email")){
self.defaults.setBool(true, forKey: "isLogged")
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){
print(result)
}
})
}
}
}
I thought about verify the user "session" in AppDelegate and change the rootViewController of storyboard. Is it a good practice or a crazy idea?
Can someone help me?
I found a way:
First set the main screen as root view in storyboard
Second step is verify if the user is logged in AppDelegate.
If the user is not logged show change root view controller to login view.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
if (self.defaults.stringForKey("isLogged") == nil){
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let initialViewController = storyboard.instantiateViewControllerWithIdentifier("LoginViewController")
self.window?.rootViewController = initialViewController
self.window?.makeKeyAndVisible()
}
return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}
And finishing, add a segue from login view to Main view with specific identifier... and when the user successfully login call self.performSegueWithIdentifier("segueIdentifier", sender: nil)
if (self.defaults.stringForKey("isLogged") != nil){
self.performSegueWithIdentifier("facebookLoginSegue", sender: nil)
}

Facebook FBSDKLoginManager/logInWithReadPermissions Swift Example not using Parse

Where is the latest Facebook Swift Documentation. I can't get the FB Login Dialog to show up. The call to loginWithReadPermissions never returns?
import UIKit
import FBSDKCoreKit
import FBSDKLoginKit
class ViewController: UIViewController {override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let loginManager = FBSDKLoginManager()
loginManager.logInWithReadPermissions(["basic_info", "email", "user_likes"], fromViewController: self.parentViewController, handler: { (result, error) -> Void in
if error != nil {
print(FBSDKAccessToken.currentAccessToken())
} else if result.isCancelled {
print("Cancelled")
} else {
print("LoggedIn")
}
})
}
You code should work if you exclude "user_likes" from permissions.
From facebook docs:
If your app asks for more than public_profile, email and user_friends, Facebook must review it before you release it. Learn more about the review process and what's required to pass review.
https://developers.facebook.com/docs/facebook-login/permissions/v2.5#reference-user_likes
Another problem may be that you have not set correctly the FacebookSDK in your project. See this tutorial: https://developers.facebook.com/docs/ios/getting-started/
So the answer is to use FBSDKLoginButton with the following
In the class declaration of the viewController
import FBSDKCoreKit
import FBSDKLoginKit
class ViewController: UIViewController, FBSDKLoginButtonDelegate
Then show the FBLogin Button with
// Setup the FB Login/Logout Button FB will take care of the
// verbiage based on the current access token
let loginView : FBSDKLoginButton = FBSDKLoginButton()
self.view.addSubview(loginView)
loginView.center = self.view.center
loginView.readPermissions = ["public_profile", "email", "user_friends"]
loginView.delegate = self
// If we have an access token, then let's display some info
if (FBSDKAccessToken.currentAccessToken() != nil)
{
// Display current FB premissions
print (FBSDKAccessToken.currentAccessToken().permissions)
// Since we already logged in we can display the user datea and taggable friend data.
self.showUserData()
self.showFriendData()
}
Show the users info with
func showUserData()
{
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: ["fields" : "id, name, gender, first_name, last_name, locale, email"])
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if ((error) != nil)
{
// Process error
print("Error: \(error)")
}
else
{
let userName : NSString = result.valueForKey("name") as! NSString
print("User Name is: \(userName)")
if let userEmail : NSString = result.valueForKey("email") as? NSString {
print("User Email is: \(userEmail)")
}
}
})
}
And to display the taggable friends
func showFriendData()
{
let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me/taggable_friends?limit=999", parameters: ["fields" : "name"])
graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in
if ((error) != nil)
{
// Process error
print("Error: \(error)")
}
else
{
if let friends : NSArray = result.valueForKey("data") as? NSArray{
var i = 1
for obj in friends {
if let name = obj["name"] as? String {
print("\(i) " + name)
i++
}
}
}
}
})
}

Resources