Tuesday, January 12, 2016

Facebook SDK and Swift - Create a Facebook Login Button

Update (November 7, 2016) - Swift 3.0.1 (Xcode 8.1)
This tutorial shows how to create a Facebook login button using Swift 2.1.1 (Xcode 7.2).

Objective-C programmers may directly refer to the instructions in Quick Start for iOS (Login with your Facebook account and select iOS.)

Steps to create a Facebook login button


1. Download Facebook SDK for iOS and unzip it to your preferred directory.

2. Create a new Facebook App online.

Login with your Facebook account and select iOS.

Enter the App Name and select Create New Facebook App ID



3. Create an iOS Single View Application with Xcode.

4. Drag these framework files into the Xcode project.
FBSDKCoreKit.Framework
FBSDKLoginKit.Framework
FBSDKShareKit.Framework

Bolts.framework //Update Nov. 7, 2016 with Xcode 8.1
//See Why am I getting an error regarding Bolts framework and FacebookSDK when I'm not even using Bolts?



5. Right-click on
Info.plist and select Open As -> Source Code.




6. Copy and paste XML snippets from Configure your info.plist section of the Quick Start for iOS webpage the into Info.plist.




<key>CFBundleURLTypes</key>
<array>
  <dict>
  <key>CFBundleURLSchemes</key>
  <array>
    <string>fb16xxxxxxxxxxxx15</string>
  </array>
  </dict>
</array>
<key>FacebookAppID</key>
<string>16xxxxxxxxxxxx15</string>
<key>FacebookDisplayName</key>
<string>Login_AppName</string>

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>facebook.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
            <false/>
        </dict>
        <key>fbcdn.net</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
            <false/>
        </dict>
        <key>akamaihd.net</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
            <false/>
        </dict>
    </dict>
</dict>
<key>LSApplicationQueriesSchemes</key>
<array>
  <string>fbapi</string>
  <string>fb-messenger-api</string>
  <string>fbauth2</string>
  <string>fbshareextension</string>
</array>

6. Copy the Bundle Identifier from Xcode and paste it into the Supply us with your Bundle Identifier section of the Quick Start for iOS webpage



7. Disable in-app purchases in the Track App Installs and App Opens section.



Then follow steps 8 and 9 and you may ignore the Track App Installs and App Opens and Let's test out your integration sections in Objective-C.

8. Modify AppDelegate.swift as:

Update (November 7, 2016) with  Xcode 8.1 (Swift 3.0.1):


import UIKit
import FBSDKCoreKit
import FBSDKLoginKit
import FBSDKShareKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    
    func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
        return FBSDKApplicationDelegate.sharedInstance().application(app, open: url as URL!, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String, annotation: options[UIApplicationOpenURLOptionsKey.annotation])
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
        return true

    }

    func applicationWillResignActive(_ application: UIApplication) {
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        FBSDKAppEvents.activateApp()
    }

    func applicationWillTerminate(_ application: UIApplication) {
    }

}

Original solution (January 12, 2016) with Xcode 7.2 (Swift 2.1.1):

import UIKit
import FBSDKCoreKit
import FBSDKLoginKit
import FBSDKShareKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
        return FBSDKApplicationDelegate.sharedInstance().application(application, openURL: url, sourceApplication: sourceApplication, annotation: annotation)
    }

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        
        FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
        
        return true
    }

    func applicationWillResignActive(application: UIApplication) {
    }

    func applicationDidEnterBackground(application: UIApplication) {
    }

    func applicationWillEnterForeground(application: UIApplication) {
    }

    func applicationDidBecomeActive(application: UIApplication) {
        FBSDKAppEvents.activateApp()
    }

    func applicationWillTerminate(application: UIApplication) {
    }
}

9. Modify ViewController.swift as:

import UIKit
import FBSDKLoginKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let loginButton = FBSDKLoginButton()
        loginButton.center = view.center
        view.addSubview(loginButton)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

10. Build and run the code.

Result with the iPhone simulator:



While the login button is pressed, the Facebook login page is displayed.

You may see this error in the output:

-canOpenURL: failed for URL: "fbauth2:/" - error: "(null)"


This is an Xcode warning indicating the the canOpenURL: call returned false. As long as you have configured the LSApplicationQueriesSchemes entry in your plist as described above, you can ignore this warning

This error should not appear with iPhone / iPad  devices.

11. The Facebook button becomes Log out after logging in.






12. Try to logout and login again. If the account information is remembered after logout as below:




Then try to clear the Safari cache:

Settings -> Safari -> Advanced (at the bottom) -> Website Data -> Edit -> facebook.com -> Delete

So the Facebook login button is working!!

Additional Information

To manage your Facebook apps online, go to Facebook Developers. Select My Apps and your app name.



If you see this error on iPhone:

App Not Setup: This app is still in development mode, and you don't have access to it. Switch to a registered test user or ask an app admin for permissions.




Try to change to the developer account (Clear Safari cache in Step 12.) or:

Make this app available to the general public or add testers:

Related Information:
Facebook SDK for iOS - Getting Started

Facebook SDK and Swift - Get Facebook SDK Version
Facebook SDK for iOS Changelog (SDK Version History)
Facebook Login Review Guide (App review by Facebook is required in some conditions.)
Facebook SDK and Swift - Display User Name and Profile Picture
Facebook SDK and Swift - Create a custom login button programmatically

Google Sign-In for iOS - Create a GIDSignInButton programmatically in Swift

21 comments:

  1. Hi Enoch,
    THANKS so much for the tutorial! first swift 2.0 fb login tutorial i have seen so far. i followed all the steps. The login worked just fine but there seems to be a problem with my app. I connect the login view to my app which starts from a navigation view. So I hooked up the loginview to the navigation controller by using segue (present modally) and gave the segue an id. Strange thing happens from here. Once i build and run the app it just shows me the login button and then I can login use my account but once I logged it doesn't present me the real app i want to show user. it just shows a logout button. Could you pls help me with this? maybe let me know what can possible go wrong with it. thanks a lot!

    ReplyDelete
    Replies
    1. Hi, you may try activating the navigation controller in:

      func loginButton(loginButton: FBSDKLoginButton!, didCompleteWithResult result: FBSDKLoginManagerLoginResult!, error: NSError!)

      You'll need FBSDKLoginButtonDelegate. Here is an example:

      Facebook SDK and Swift - Display User Name and Profile Picture

      Delete
  2. Hi, thanks a lot for the reply! i have tried out using the loginButtonDelegate and modified the viewController and info.plist almost the same (just didn't have imageView included) as yours but still not working. Once i logged in it just pops a logout button. I have 2 views connected to a navigation controller and I plug the fb login view into the app as the very first view. The fb loginview has also been set as the initial view and it is connected to the navigation view with the segue (modally). Sorry i am not sure how to post a pic of my spring board but i will try. Thanks again for the help!

    ReplyDelete
    Replies
    1. Can you please paste the URL of your picture here or insert the picture in a StackOverflow question? Thanks!

      Delete
  3. sorry, i mean storyboard. and here is my screen shot of the storyboard
    /Users/diii/Desktop/Screen Shot 2016-01-28 at 4.16.55 PM.png

    ReplyDelete
    Replies
    1. Please provide a valid URL, such as a shared link of Google drive.

      Delete
    2. Sorry Enoch, I am quite new to the blog. i have attached some pics in my google+. here is the links
      https://plus.google.com/u/0/117633541457089161722/posts/JUmGFSxjxJk?pid=6244768160245814322&oid=117633541457089161722

      https://plus.google.com/u/0/117633541457089161722/posts/JUmGFSxjxJk?pid=6244768910912299666&oid=117633541457089161722

      https://plus.google.com/u/0/117633541457089161722/posts/JUmGFSxjxJk?pid=6244768908043962242&oid=117633541457089161722

      Thanks for the help!

      Delete
    3. Hi Andy, I've seen your pics. As I mentioned previously, you probably need to add some code in func loginButton(... didCompleteWithResult ...) to activate a new view controller.

      Sorry I haven't worked with storyboard for a while. You should be able to find some tutorials about how to connect the segue or other storyboard components to the code.

      If you want to start a new view controller programmatically, try calling presentViewController.

      Delete
  4. swift 3 how can i display fb username profile picture

    ReplyDelete
  5. I get the page that is the option to login, but then it doesn't take me to a logout button (You have already authorized __ account, etc). It just says that I am not logged in. Why could this be?

    ReplyDelete
    Replies
    1. uh... no idea. I just tried my Swift 3 solution a couple of days ago. There was no problem.

      Delete
  6. Thanks a lot for this tutorial. I've been able to put together a Login Screen (http://iosapptemplates.com/templates/login-screen-in-swift-3-freebie) that also supports integration with Twitter. Open-sourced it, so that others can take advantage of it.

    ReplyDelete
  7. Health Is God expects to convey the most ideal wellbeing surveys of the supplement accumulations and different wellbeing generation that range from skincare to mind, muscle, male upgrade and cerebrum wellbeing conditions. You, the client are of most extreme significance to us, and we are focused on being the entrance that maintains your sound way of life.

    ReplyDelete
  8. This comment has been removed by a blog administrator.

    ReplyDelete
  9. HealRun is a health news blog we provide the latest news about health, Drugs and latest Diseases and conditions. We update our users with health tips and health products reviews. If you want to know any information about health or health product (Side Effects & Benefits) Feel Free To ask HealRun Support Team.

    ReplyDelete
  10. This comment has been removed by a blog administrator.

    ReplyDelete
  11. This comment has been removed by a blog administrator.

    ReplyDelete
  12. Let me explore an abundance of the potential dilemmas to consider. Keto Advanced Fat Burner is the complete package. Keto Advanced Fat Burner pertains to all kinds of Keto Advanced Fat Burner. That's sort of elastic. Don't worry, you might be wondering by now whether Keto Advanced Fat Burner actually worth all the hassle. Keto Advanced Fat Burner is only trickery in the greater scheme of things.

    Keto Advanced Fat Burner

    ReplyDelete

  13. I actually ought to take care of my Keto Advanced Fat Burner today and I am trying to escape from my Keto Advanced Fat Burner rut. My notion is based around my assumption that few big cheeses have a perception about Keto Advanced Fat Burner. There is stuff you may do to discover something which is economical and impressive. Don't let me down. As usual, that's one of my Keto Advanced Fat Burner.


    Keto Advanced Fat Burner

    ReplyDelete
  14. Apply These 8 Secret Techniques To Improve Ecommerce Business Ideas For 2022 - https://www.reviewengin.com/10-ecommerce-business-ideas-2022/

    ReplyDelete