coding_cover676x469
Lately we’ve been doing some iPhone app to familiarize with Swift. During our research process we came across an amazing mobile app platform: Parse.

With Parse you can use login with Facebook / Twitter and create/connect to a database in no time!

Time for this Tutorial: 40min

1- Set Up Parse and Facebook App

Let’s go ahead and and create a new user on Parse.com. Then create a new app on parse.
1
Then login to facebook and go to the app developer page: https://developers.facebook.com/apps/
Go ahead and create a new app. Choose iOS. Then choose a name for your app and a category then click “create app ID”.
2
You will then be prompt to a ‘quick start’ page. First thing to do is to Download the Facebook SDK. You can also download it here.
Then go to Xcode and create a new project. Choose a Single View Application. Click “Next”.
3
On the next screen, choose a product name, an organization name and identifier.
Note the your app Bundle Identifier will be : organization_identifier.product_name.
I choosed parseLogin as Product Name and tutorial as Organization Identifier. My Bundle Identifier is going to be: tutorial.parseLogin. Click “Next” then choose a repository for your app.
4
Congratulation you create your app!
Now we need to connect it to Facebook and Parse.

2- Let’s start with Facebook

First thing you do in your app is to create a Frameworks group. Go ahead and right click on your app name on the left inside in Xcode. Choose “New Group” and call it “Frameworks”. You will drag and drop all the external librairy into this Group.

Double click on the file you previously download on the facebook app page (facebook-ios-sdk-3.23.1.pkg). Go ahead and install it. It should create a folder “FacebookSDK” in your “~/Documents”. Once installed navigate to the folder. Remove all the files except “FacebookSDK.framework” and “FBAudienceNetwork.framework”. You should now have your folder “FacebookSDK” with 2 framework files in it.
Drag and Drop those 2 files to your Xcode window under the “Frameworks” group. Keep everything as is is on the pop up and click “Finish”.
5
Now in the “Supporting Files” folder click the Info.plist file.
You’re going to add the Facebook app ID / name.
In the .plist create a key called “FacebookAppID” with String as Type and copy your AppID XXXXXXXXXXXX as a string to the value field.
In the .plist create a key called “FacebookDisplayName” with String as Type and copy your App Name XXXXXXXX as a string to the value field.
In the .plist create a key called “URL Type” with Array as Type with a dictionary as its only child. That dictionary needs one array as child called “URL Schemes”. The child of that array is a String with “fbXXXXXXXXXX” as a value (XXXXXXX is here you APP ID).
5b
Now go back to the facebook page “Quick Starts” and add the bundle identifier of the app (here tutorial.parseLogin). Hit “Next” and scroll all the way down until you see finished!
Then all the way on top of the page click “Skip Quick Start”.
5c
On your app page on Facebook go to “Status & Review” on the left menu. Under “Do you want to make this app and all its live features available to the general public?” turn the button to “YES”.
5cc
The last thing you will need is you app Secret. Then you should be done with the Facebook side of the Force ;) So on the app page on facebook click “show” in the app secret section. FB will ask for your password again. Then copy the app secret.
5d

3- Let’s set up Parse

Go back to Parse and click “Settings” on the top menu then “Authentification” in the left menu.
There you see a “Facebook Apllication” section. Type there you app ID and app Secret.
5e
Then still in Parse on the top Menu click “Docs” then click “download the SDK” under the “IOS SDK” section. On the new page choose in the “IOS” section “SDK”. It will download the SDK as a Zip. Unzip the file.
Your can also download the SDK here

Select Bolts / Parse / ParseFacebookUtils and drag and drop them to the Xcode Window in your Framework group. Follow the same as you did for the Facebook SDK.

Now we are going to link all the framework we need to run Parse and Facebook.
Go the the “build phase” of your app in Xcode.
6
You can see that the app already has 4 linked Libraries (the Facebook and Parse libraries we imported previously). If you don’t have that, there is something wrong.

Click the + button in the bottom left of the ‘Link Binary With Libraries’ section and add the following libraries:

  • Accounts.framework
  • AudioToolbox.framework
  • CFNetwork.framework
  • CoreGraphics.framework
  • CoreLocation.framework
  • MobileCoreServices.framework
  • QuartzCore.framework
  • Security.framework
  • Social.framework
  • StoreKit.framework
  • SystemConfiguration.framework
  • libz.dylib
  • libsqlite3.dylib

6b
Now we need a little twist to be able to use those librairy into our Swift project: Those librairies are written in Objective C and our app is coded in Swift. But no worries we can create a Bridge between those. They is no real way to create a Bridge file. The only way I found so far is to create an objective C class. So on Xcode on the left inside right click on your app name folder (for me parseLogin) and choose “New File”. Choose “Coca Touch Class”.
7
Then on the next screen choose for Language Objective C. The name of the class doesn’t matter since you’ll delete that file once the Bridge File created.
8
Go ahead and click “Create”. A pop up will appear to ask if you want to configure a Objective-C bridging header. Go ahead and click “Yes”.
9
You see 3 files have been added : the “.h” and “.m” of your class and the APPName_Bridging-Header.h (for me parseLogin-Bridging-Header.h).

Now you can delete the 2 files create for the class and choose move to Trash.
10
Now go to the Bridging-Header file and paste those lines:

//
// Use this file to import your target's public headers that you would like to expose to Swift.
//
#import <FacebookSDK/FacebookSDK.h>
#import <Parse/Parse.h>
#import <ParseFacebookUtils/PFFacebookUtils.h>

You can now use Facebook and Parse in Swift.

4- Let’s start Coding!

The first things we need to do it to set the Parse app Id and Client Key as well as initialize Facebook.
Go to the AppDelegate.swift file.
Add in the application function the following:

Parse.setApplicationId("PARSE_APP_ID", clientKey:"PARSECLIENT_KEY")
PFAnalytics.trackAppOpenedWithLaunchOptionsInBackground(launchOptions?, block: nil)
PFFacebookUtils.initializeFacebook()

Your Parse App Id and Client Key can be both found on the parse website under Settings -> Keys
11
Replace the function func applicationDidBecomeActive(application: UIApplication{} with:

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.
         FBAppCall.handleDidBecomeActiveWithSession(PFFacebookUtils.session())
    }

At the bottom of your file add the following functions before the last }

func application(application: UIApplication,
        openURL url: NSURL,
        sourceApplication: String?,
        annotation: AnyObject?) -> Bool {
            return FBAppCall.handleOpenURL(url, sourceApplication:sourceApplication,
                withSession:PFFacebookUtils.session())
}

Those functions handled the callback from Facebook.
Your AppDelegate.swit should look like this:

//
//  AppDelegate.swift
//  parseLogin
//
//  Created by Auriga on 3/10/15.
//  Copyright (c) 2015 Oskoui+Oskoui. All rights reserved.
//
 
import UIKit
 
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
 
    var window: UIWindow?
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        Parse.setApplicationId("PARSE_APP_ID", clientKey:"PARSECLIENT_KEY")
        PFAnalytics.trackAppOpenedWithLaunchOptionsInBackground(launchOptions?, block: nil)
        PFFacebookUtils.initializeFacebook()
        return true
    }
 
    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.
         FBAppCall.handleDidBecomeActiveWithSession(PFFacebookUtils.session())
    }
 
    func applicationWillTerminate(application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }
 
    func application(application: UIApplication,
        openURL url: NSURL,
        sourceApplication: String?,
        annotation: AnyObject?) -> Bool {
            return FBAppCall.handleOpenURL(url, sourceApplication:sourceApplication,
                withSession:PFFacebookUtils.session())
    }
}

Ok it’s time to launch the app on the iPhone Simulator! Go ahead and click the Build Button.

Boom your app opens on the Simulator but you only see a blank screen. That’s normal, we haven’t done anything yet!

Let’s go ahead and add a button to your View!
Locate the Main.storyboard file and click on it.
Drag and drop a UIButton to your view. I change the title of it to be Login with Facebook.
Now let’s go ahead and connect a click action to the button.
12
Now we need to write the function that will be called when someone hit the Button.

Go the ViewController.swift and add a new attribute to your class:

let permissions = ["public_profile"]

and paste this function:

@IBAction func fbLoginClick(sender: AnyObject) {
   PFFacebookUtils.logInWithPermissions(self.permissions, {
            (user: PFUser!, error: NSError!) -> Void in
            if user == nil {
                NSLog("Uh oh. The user cancelled the Facebook login.")
            } else if user.isNew {
                NSLog("User signed up and logged in through Facebook! \(user)")
            } else {
                NSLog("User logged in through Facebook! \(user)")
            }
  })
}

UPDATED VERSION SWIFT 1.3

@IBAction func fbLoginClick(sender: AnyObject) {
        PFFacebookUtils.logInWithPermissions(self.permissions, /*block; added*/block: {
            (user: PFUser?, error: NSError?) -> Void in //switched ! to ?
            if user == nil {
                NSLog("Uh oh. The user cancelled the Facebook login.")
            } else if user!.isNew { //inserted !
                NSLog("User signed up and logged in through Facebook!")
            } else {
                NSLog("User logged in through Facebook! \(user!.username)")
            }
        })
 
    }

Your ViewController should look like this:

//
//  ViewController.swift
//  parseLogin
//
//  Created by Auriga on 3/10/15.
//  Copyright (c) 2015 Oskoui+Oskoui. All rights reserved.
//
 
import UIKit
 
class ViewController: UIViewController {
    let permissions = ["public_profile"]
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
 
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
 
    @IBAction func fbLoginClick(sender: AnyObject) {
        PFFacebookUtils.logInWithPermissions(self.permissions, {
            (user: PFUser!, error: NSError!) -> Void in
            if user == nil {
                NSLog("Uh oh. The user cancelled the Facebook login.")
            } else if user.isNew {
                NSLog("User signed up and logged in through Facebook! \(user)")
            } else {
                NSLog("User logged in through Facebook! \(user)")
            }
        })
    }
 
 
}

The @IBAction at the beginning of the func declaration let Xcode knows that this function is going to be attached to the interface file. (for us our button we created).
Double click on the ViewController.swift to open it outside of Xcode so you can have the Main.storyboard and the ViewController.swift open at the same time.
In the storyboard click on the Button we created and go to “Show the connections Inspector”
13
Next to the Touch Up Inside on the right you see a little circle. If you hover on it you’ll see a “+” sign appearing click on it a drag it on your function you just created in the ViewController.
14
Now Run the app!
Tada you have a FB login button. Click on it and it should prompt you to request access on Facebook web app.
15
If you click OK then you will be redirected to the app and you can see in the console that the signed up and logged in through Facebook!
YOU DID IT! See wasn’t that hard.
16
You can also see in Parse -> Core that a user has been added to the DB!

17

Useful links:

BONUS! Get user infos from Facebook:

func getUserInfo() {
        if let session = PFFacebookUtils.session() {
            if session.isOpen {
                println("session is open")
                FBRequestConnection.startForMeWithCompletionHandler({ (connection: FBRequestConnection!, result: AnyObject!, error: NSError!) -> Void in
                    //println("done me request")
                    if error != nil {
                        println("facebook me request - error is not nil :(")
                    } else {
                        println("facebook me request - error is nil :)  ")
                        let urlUserImg = "http://graph.facebook.com/\(result.objectID)/picture?type=large"
                        let firstName = result.first_name
                        let lastName = result.last_name
                    }
                })
            }
        } else {
            //let user:PFUser = PFUser.currentUser()
            //println("ohooo \(user)")
 
 
        }
    }