
Note: Newer tutorial available. If you would like to learn how to implement Facebook Login using Facebook SDK 4.0 using Swift, read Tutorial: How To Use Login in Facebook SDK 4.0 for Swift
If you are building a new game for iOS one of the key features you are going to need is a way to capture user information to populate their profile and for Facebook Leaderboards so users can compete against their friends.
As we are all getting up to speed with Swift, I’ve been working on a couple new games and I came across a few issues when trying to incorporate existing frameworks into my project, like the Facebook SDK.
Below is a tutorial to help you add the existing Facebook SDK into your Swift project. This will be useful until Facebook releases an update to their SDK that supports Swift.
Setting up the Facebook SDK in Your Swift App
- Visit the Getting Started with the Facebook iOS SDK documentation to download the Facebook SDK and install it.
- Add the FacebookSDK.Framework to your project as you normally would. Drag it or add it using the “Linked Frameworks and Libraries” within your target settings.
- You won’t be able to use the normal #import <FacebookSDK/FacebookSDK.h> to link the framework so you need to do a work around by creating a Bridging Header.
- Create a new “Objective-C” Header file by clicking “File > New”
- All you need in the Bridging-Header.h is the import statement for the Facebook SDK.
// // Bridging-Header.h // SwiftBook #import
- Next you need to add it to your target’s build settings:In Xcode, if you go into the build settings for your target, and scroll all the way down you’ll find a “Swift Compiler – Code Generation” section.
Set “Objective-C Bridging Header” to <#PROJECT_NAME>/Bridging-Header.h
“Install Objective-C Compatibility Header”, should be set to “Yes”.
- Now your app should be able to access all of the APIs in the Facebook SDK.
- Now we’ll setup our app to use Facebook Login.
- Add the following to your AppDelegate.swift. The “OpenURL” method allows your app to open again after the user has validated their login credentials.
// // AppDelegate.swift // SwiftBook // // Created by Brian Coleman on 2014-07-07. // Copyright (c) 2014 Brian Coleman. All rights reserved. //import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool { // Override point for customization after application launch. FBLoginView.self FBProfilePictureView.self return true } func application(application: UIApplication, openURL url: NSURL, sourceApplication: NSString?, annotation: AnyObject) -> Bool { var wasHandled:Bool = FBAppCall.handleOpenURL(url, sourceApplication: sourceApplication) return wasHandled } func applicationWillResignActive(application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } func applicationDidEnterBackground(application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } func applicationWillEnterForeground(application: UIApplication) { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } func applicationDidBecomeActive(application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } func applicationWillTerminate(application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } }
- Add the FBLoginViewDelegate methods to your ViewController.swift.
// // ViewController.swift // SwiftBook // // Created by Brian Coleman on 2014-07-07. // Copyright (c) 2014 Brian Coleman. All rights reserved. //import UIKit import UIKit class ViewController: UIViewController, FBLoginViewDelegate { @IBOutlet var fbLoginView : FBLoginView! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. self.fbLoginView.delegate = self self.fbLoginView.readPermissions = ["public_profile", "email", "user_friends"] } // Facebook Delegate Methods func loginViewShowingLoggedInUser(loginView : FBLoginView!) { println("User Logged In") } func loginViewFetchedUserInfo(loginView : FBLoginView!, user: FBGraphUser) { println("User: \(user)") println("User ID: \(user.objectID)") println("User Name: \(user.name)") var userEmail = user.objectForKey("email") as String println("User Email: \(userEmail)") } func loginViewShowingLoggedOutUser(loginView : FBLoginView!) { println("User Logged Out") } func loginView(loginView : FBLoginView!, handleError:NSError) { println("Error: \(handleError.localizedDescription)") } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }
Notice that I have used the exactly same FBLoginViewDelegate methods as used in Objective-C but reformatted the method calls to support the new Swift syntax.
Here’s an example:
- (void)loginViewFetchedUserInfo:(FBLoginView *)loginView user: (id)user;
- The method name starts with “loginViewFetchedUserInfo”. That stays the same.
- The parameter is a pointer of type “FBLoginView” This will get translated to an optional of type FBLoginView because it can be nil. The convention is to make it an Implicitly Unwrapped Optional so it will become FBLoginView!
- Protocols are types in and of themselves in Swift, so the user parameter will become simply FBGraphUser.
- The first parameter in a swift method is assumed to be just an internal name so the parameter can be named anything but for consistency we will name it the same: “loginView”
- The second parameter in a swift method is assumed to be both internal and external. In the Objective-C version they happen to be the same so we can simply use it once and Swift will make it both the internal and external name
This leaves us with this translation:
func loginViewFetchedUserInto(loginView : FBLoginView!, user: FBGraphUser)
- Add a UIView to your Storyboard and hookup the outlet of the view to fbLoginView.
- There is one final step needed to be performed, and that is to add three new keys to the project’s .plist file. So, open it by clicking on the Supporting Files group in the Project Navigator and then on the Info.plist file. Add a new key named FacebookAppID, and as its value paste the App ID value which you can copy from the Facebook dashboard, at the top of it. Similarly, add the FacebookDisplayName key, and in its value paste the Display Name.Finally, create a new key named URL Types, and set its type to array with one item only. Give it the URL Schemes title and make it an array too. In the one and only item that should be contained, set the app ID value you copied from the Facebook dashboard, prefixing it with the fb literal. The image below shows all the three additions on the .plist file:
- Compile your project and you should see the following screen. Once you click the “Log in with Facebook” button, it should kick you out to the Facebook App or the Facebook website for the user to login. After they have, it’ll kick back to your app and you’ll see the user information in the console.
Now it’s up to you to use the users information as you wish. Maybe to populate a user profile or to pull the users Facebook friends so you can build a leaderboard.
You can grab the full source code for this tutorial. Note: Updated for XCode6-Beta4.
I hope this helped you get through a couple hurdles with integrating Facebook Login in Swift. If you run into some errors and you think everything should be fine, try Cleaning the project “Product > Clean” or restart your project file. Xcode 6 is currently in beta, and I’ve had a lot of issues with it so far. Hopefully Apple will release an update soon that fixes some of the initial bugs with the compiler.