Last active
March 10, 2019 14:56
-
-
Save ShawnBaek/1397f2ac4bb4d0b90c5f9e37ecc50ca9 to your computer and use it in GitHub Desktop.
ParseServerManager for iOS
This file contains 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
@IBAction fileprivate func facebookTapped(_ sender: Any) { | |
ParseServerManager.shared.loginWithFacebook { [weak self] results in | |
guard let self = self else { | |
return | |
} | |
self.handleLogin(results) | |
} | |
} | |
@IBAction fileprivate func twitterTapped(_ sender: Any) { | |
ParseServerManager.shared.loginWithTwitter { [weak self] results in | |
guard let self = self else { | |
return | |
} | |
self.handleLogin(results) | |
} | |
} | |
@IBAction fileprivate func loginTapped(_ sender: Any) { | |
guard let id = idTextField.text, let password = passwordTextField.text else { | |
return | |
} | |
ParseServerManager.shared.login(username: id, password: password) { [weak self] results in | |
guard let self = self else { | |
return | |
} | |
self.handleLogin(results) | |
} | |
} | |
fileprivate func handleLogin(_ results: LoginHandler) { | |
switch results { | |
case .success(let .some(title), let .some(message)): | |
//Add Your Logic | |
break | |
case .failure(let message): | |
//Add Your Logic | |
break | |
case .success: | |
//Add Your Logic | |
break | |
} | |
} |
This file contains 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
func configureParse() { | |
User.registerSubclass() | |
} | |
func application( | |
_ application: UIApplication, | |
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? | |
) -> Bool { | |
Fabric.with([Crashlytics.self]) | |
Parse.enableLocalDatastore() | |
Parse.setLogLevel(PFLogLevel.info); | |
let configuration = ParseClientConfiguration { | |
$0.applicationId = "" | |
$0.clientKey = "" | |
$0.server = "https://parseapi.back4app.com/" | |
} | |
Parse.initialize(with: configuration) | |
PFTwitterUtils.initialize(withConsumerKey: "", consumerSecret: "") | |
PFFacebookUtils.initializeFacebook(applicationLaunchOptions: launchOptions) | |
PFConfig.getInBackground{(config: PFConfig?, error: Error?) -> Void in | |
if error == nil { | |
//Handle | |
} | |
} | |
PFUser.enableAutomaticUser() | |
configureParse() | |
return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions) | |
} | |
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool { | |
return FBSDKApplicationDelegate.sharedInstance().application( | |
application, | |
open: url, | |
sourceApplication: sourceApplication, | |
annotation: annotation | |
) | |
} |
This file contains 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
// | |
// ParseServerManager.swift | |
// | |
// Created by ShawnBaek on 9/9/18. | |
// Copyright © 2018 ShawnBaek. All rights reserved. | |
// | |
import Foundation | |
import Parse | |
enum LoginHandler { | |
case success(title: String?, message: String?) | |
case failure(String?) | |
} | |
class ParseServerManager { | |
static let shared = ParseServerManager() | |
private init() { } | |
func login(username: String, password: String, completion: @escaping (_ handler: LoginHandler) -> Void) { | |
User.logInWithUsername(inBackground: username, password: password) { parseUser, error in | |
if let userAccount = parseUser, | |
let id = userAccount.username, | |
error == nil { | |
UserDefaults.standard.set(id, forKey: "username") | |
UserDefaults.standard.synchronize() | |
completion(.success(title: nil, message: nil)) | |
} else { | |
completion(.failure(error?.localizedDescription)) | |
} | |
} | |
} | |
func signup(username: String, password: String, completion: @escaping (_ handler: LoginHandler) -> Void) { | |
let currentUser = PFUser() | |
currentUser.username = username | |
currentUser.email = username | |
currentUser.password = password | |
currentUser.signUpInBackground { success, error in | |
guard success, error == nil else { | |
completion(.failure(error?.localizedDescription)) | |
return | |
} | |
//linkFaceBook? | |
completion(.success(title: "Registration is successful", message: nil)) | |
} | |
} | |
func loginWithTwitter(completion: @escaping (_ handler: LoginHandler) -> Void) { | |
PFTwitterUtils.logIn { [weak self] user, error in | |
guard let self = self else { | |
return | |
} | |
if let user = user { | |
if user.isNew { | |
self.getTwitterData() { results in | |
completion(results) | |
} | |
} else { | |
completion(.success(title: nil, message: nil)) | |
} | |
} else { | |
completion(.failure(error?.localizedDescription)) | |
} | |
} | |
} | |
fileprivate func getTwitterData(completion: @escaping (_ handler: LoginHandler) -> Void) { | |
guard let twitter = PFTwitterUtils.twitter(), | |
let twitterId = twitter.userId, | |
// let twitterScreenName = twitter.screenName, | |
let twitterAPIURL = URL(string: "https://api.twitter.com/1.1/account/verify_credentials.json"), | |
let currentUser = User.current() else { | |
completion(.failure("Can't fetch twitter account")) | |
return | |
} | |
let request = NSMutableURLRequest(url: twitterAPIURL) | |
twitter.sign(request) | |
URLSession.shared.dataTask(with: request as URLRequest) { data, response, error in | |
guard let fetchedData = data, let json = try? JSONSerialization.jsonObject( | |
with: fetchedData, | |
options: .mutableContainers | |
) as? NSDictionary, | |
let fetchedJSON = json, | |
error == nil else { | |
completion(.failure(error?.localizedDescription)) | |
return | |
} | |
if let profileImagePath = fetchedJSON["profile_image_url"] as? String, | |
let profileImageURL = URL(string: profileImagePath), | |
let profileImageData = try? Data(contentsOf: profileImageURL), | |
let profileFileObject = PFFileObject(data: profileImageData) { | |
currentUser.setObject(profileFileObject, forKey: "profileImg") | |
} | |
currentUser.username = twitterId | |
currentUser.saveInBackground(block: { (success, error) in | |
guard error == nil, success else { | |
completion(.failure(error?.localizedDescription)) | |
return | |
} | |
UserDefaults.standard.set(twitterId, forKey: "username") | |
UserDefaults.standard.synchronize() | |
completion(.success(title: nil, message: nil)) | |
}) | |
}.resume() | |
} | |
func loginWithFacebook(completion: @escaping (_ handler: LoginHandler) -> Void) { | |
let permissions = ["public_profile", "email"] | |
PFFacebookUtils.logInInBackground( | |
withReadPermissions: permissions, | |
block: { [weak self] parseUser, error in | |
guard let self = self else { | |
return | |
} | |
if let facebookUser = parseUser, error == nil { | |
if facebookUser.isNew { | |
self.getFaceBookUserData(completion: { results in | |
completion(results) | |
}) | |
} | |
else { | |
UserDefaults.standard.set(facebookUser.username, forKey: "username") | |
UserDefaults.standard.synchronize() | |
completion(.success(title: nil, message: nil)) | |
} | |
} else { | |
completion(.failure(error?.localizedDescription)) | |
} | |
}) | |
} | |
fileprivate func getFaceBookUserData(completion: @escaping (_ handler: LoginHandler) -> Void) | |
{ | |
let requestParameters = ["fields": "id, email"] | |
let userDetails : FBSDKGraphRequest = FBSDKGraphRequest(graphPath: "me", parameters: requestParameters) | |
userDetails.start(completionHandler: { connection, result, error in | |
guard let dict = result as? [String: AnyObject], | |
let userId = dict["id"] as? String, | |
let email = dict["email"] as? String, | |
let parseUser = User.current(), | |
error == nil else { | |
completion(.failure(error?.localizedDescription)) | |
return | |
} | |
parseUser.username = userId | |
parseUser.email = email | |
let userProfile = "https://graph.facebook.com/" + userId + "/picture?type=large" | |
if let profilePictureUrl = URL(string:userProfile), | |
let profilePictureData = try? Data(contentsOf: profilePictureUrl), | |
let profileFileObject = PFFileObject(data: profilePictureData) { | |
if parseUser.object(forKey: "profileImg") == nil { | |
parseUser.setObject(profileFileObject, forKey: "profileImg") | |
} | |
} | |
parseUser.saveInBackground(block: { success, error in | |
guard success, error == nil else { | |
completion(.failure(error?.localizedDescription)) | |
return | |
} | |
UserDefaults.standard.set(userId, forKey: "username") | |
UserDefaults.standard.synchronize() | |
completion(.success(title: nil, message: nil)) | |
}) | |
}) | |
} | |
func linkWithFaceBook(completion: @escaping (_ handler: LoginHandler) -> Void) { | |
guard let currentUser = User.current(), !PFFacebookUtils.isLinked(with: currentUser) else { | |
completion(.success(title: "Registration is successful. Facebook is already linked", message: nil)) | |
return | |
} | |
PFFacebookUtils.linkUser(inBackground: currentUser, withReadPermissions: nil, block: { success, error in | |
guard success, error == nil else { | |
completion(.failure("Registration is successful. Facebook linked is failed.")) | |
return | |
} | |
completion(.success(title: "Registration is successful", message: nil)) | |
}) | |
} | |
} |
This file contains 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
// | |
// User.swift | |
// | |
// Created by ShawnBaek on 12/28/17. | |
// Copyright © 2017 ShawnBaek. All rights reserved. | |
// | |
import UIKit | |
import Parse | |
class User: PFUser { | |
override class func query() -> PFQuery<PFObject>? { | |
let query = PFQuery(className: "_User") | |
query.cachePolicy = .networkElseCache | |
return query | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment