Created
April 2, 2016 12:46
-
-
Save MathieuWhite/e303ace603a6327368b049d556fae671 to your computer and use it in GitHub Desktop.
Facebook user management for login and logout in Swift.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// FacebookManager.swift | |
// | |
// Created by Mathieu White on 2016-02-07. | |
// Copyright © 2016 Mathieu White. All rights reserved. | |
// | |
import UIKit | |
import FBSDKCoreKit | |
import FBSDKLoginKit | |
let kFacebookLoggedOutNotification: String = "kFacebookLoggedOutNotification" | |
let kFacebookLoginSuccessNotification: String = "kFacebookLoginSuccessNotification" | |
/** | |
* Structure that holds the properties on the current Facebook user. | |
*/ | |
struct FacebookUser | |
{ | |
var id: String = "" | |
var firstName: String = "" | |
var lastName: String = "" | |
var email: String = "" | |
var pictureURL: String = "" | |
} | |
/// Singleton class that handles all of Facebook's API calls in the app. | |
class FacebookManager: NSObject | |
{ | |
// MARK: - Constants | |
/// The shared instance of the FacebookManager. | |
static let sharedInstance: FacebookManager = FacebookManager() | |
// The permissions to request from the Facebook API | |
private let readPermissions: [AnyObject] = [ | |
"public_profile", | |
"email", | |
] | |
/// The parameters for fetching users. | |
private let userParameters: [NSObject : AnyObject] = [ | |
"fields" : "id,first_name,last_name,email,picture{url}" | |
] | |
/// The Facebook login manager for the application. | |
private let loginManager: FBSDKLoginManager = FBSDKLoginManager() | |
// MARK: - API Routes | |
/// The API route to access the current user. | |
private let currentUserPath: String = "me" | |
// MARK: - Variables | |
/// The current user logged in through Facebook. | |
var currentUser: FacebookUser? | |
// MARK: - Initializers | |
private override init() | |
{ | |
super.init() | |
self.fetchCurrentUser() | |
} | |
// MARK: - User Access Methods | |
/** | |
This method checks if the app has access to the user's Facebook account. | |
- returns: true if the app is connected to Facebook, false otherwise | |
*/ | |
func hasUserAccess() -> Bool | |
{ | |
if let _ = FBSDKAccessToken.currentAccessToken() | |
{ | |
return true | |
} | |
return false | |
} | |
/** | |
This method handles the user's access inside the app. | |
It will either ask the user to connect with Facebook, | |
or logout, depending on the current status of the app. | |
*/ | |
func handleUserAccess() | |
{ | |
// If the user is already connected, confirm the logout | |
if (self.hasUserAccess()) | |
{ | |
self.loginManager.logOut() | |
// Notify observers that the user logged out of their Facebook account | |
NSNotificationCenter.defaultCenter().postNotificationName(kFacebookLoggedOutNotification, object: nil) | |
} | |
else | |
{ | |
// Present the user with the Facebook login screen | |
self.loginManager.logInWithReadPermissions(self.readPermissions, | |
fromViewController: nil, | |
handler: { [weak self] (result: FBSDKLoginManagerLoginResult!, error: NSError!) -> Void in | |
// Check if the app received access to the Facebook account | |
if (self?.hasUserAccess() == true) | |
{ | |
// Notify observers that the Facebook login was successful | |
NSNotificationCenter.defaultCenter().postNotificationName(kFacebookLoginSuccessNotification, object: nil) | |
// Fetch the current user | |
if (self?.currentUser == nil) | |
{ | |
self?.fetchCurrentUser() | |
} | |
} | |
}) | |
} | |
} | |
// MARK: - User Methods | |
private func fetchCurrentUser() | |
{ | |
// Initialize the request for the current user | |
let request: FBSDKGraphRequest = FBSDKGraphRequest(graphPath: self.currentUserPath, parameters: self.userParameters) | |
// Request the current user | |
request.startWithCompletionHandler({ [weak self] (connection, result, error) -> Void in | |
// Logged an error if we have one | |
if let error = error | |
{ | |
print("Error fetching Facebook user: \(error.localizedDescription)") | |
} | |
else | |
{ | |
// Initialize the new facebook user info | |
var currentUser: FacebookUser = FacebookUser() | |
// Get the result as a dictionary | |
if let result = result as? [NSObject : AnyObject] | |
{ | |
// Get the facebook user's id | |
if let id = result["id"] as? String | |
{ | |
currentUser.id = id | |
} | |
// Get the facebook user's first name | |
if let firstName = result["first_name"] as? String | |
{ | |
currentUser.firstName = firstName | |
} | |
// Get the facebook user's last name | |
if let lastName = result["last_name"] as? String | |
{ | |
currentUser.lastName = lastName | |
} | |
// Get the facebook user's email | |
if let email = result["email"] as? String | |
{ | |
currentUser.email = email | |
} | |
// Get the facebook user's picture URL | |
if | |
let picture = result["picture"] as? [NSObject : AnyObject], | |
let data = picture["data"] as? [NSObject : AnyObject], | |
let url = data["url"] as? String | |
{ | |
currentUser.pictureURL = url | |
} | |
} | |
// Set the current user | |
self?.currentUser = currentUser | |
} | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment