После многих попыток это работает для меня.
В AppDelegate импортируйте Parse, ParseFacebookUtilsV4 и FBSDKCoreKit
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
{
PFFacebookUtils.initializeFacebook(applicationLaunchOptions: launchOptions)
FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
return true
}
и добавьте два метода
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(
app,
open: url as URL?,
sourceApplication: options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String,
annotation: options[UIApplication.OpenURLOptionsKey.annotation]
)
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(
application,
open: url as URL?,
sourceApplication: sourceApplication,
annotation: annotation)
}
А затем, при входе в систему ViewController:
@IBAction func signInFacebook(_ sender: Any)
{
let permissions = ["public_profile", "email"]
PFFacebookUtils.logInInBackground(withReadPermissions: permissions) { (user : PFUser?, error: Error?) in
if(error != nil)
{
//Display an alert message
let myAlert = UIAlertController(title:"Alert", message:error?.localizedDescription, preferredStyle: UIAlertController.Style.alert)
let okAction = UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: nil)
myAlert.addAction(okAction)
self.present(myAlert, animated:true, completion:nil);
return
}
else
{
let query = PFQuery(className: "_User")
query.whereKey("email", equalTo: NSNull())
query.findObjectsInBackground (block: { (objects, error) -> Void in
if error == nil
{
// found related objects
for object in objects! {
//delete error user
print(object.value(forKey: "username")!)
object.deleteEventually()
}
}
else{
print(error!.localizedDescription)
}
}
)}
self.indicator.isHidden = false
self.indicator.startAnimating()
self.setUp.isHidden = false
if(FBSDKAccessToken.current() != nil) {
FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, email, first_name, last_name"]).start(completionHandler: { (connection, result, error) in
let resultDic = result as! [String: Any]
let nameFB = resultDic["name"] as! String
let emailFB = resultDic["email"] as! String
let idFB = resultDic["id"] as! String
let firstFB = resultDic["first_name"] as! String
let lastFB = resultDic["last_name"] as! String
// correct in case of double First or Last name
let firstFBNoSpaces = firstFB.replacingOccurrences(of: " ", with: "_", options: .literal, range: nil)
let lastFBNoSpaces = lastFB.replacingOccurrences(of: " ", with: "_", options: .literal, range: nil)
var userNameNew = firstFBNoSpaces + "_" + lastFBNoSpaces
userNameNew = userNameNew.lowercased()
// send data to server to related columns
let user = PFUser()
user.username = userNameNew.lowercased()
user.email = emailFB.lowercased()
user.password = idFB
user["fullname"] = nameFB.capitalized
UserDefaults.standard.set(user.username, forKey: "username")
// get Facebook profile picture
let userProfile = "https://graph.facebook.com/" + idFB + "/picture?type=large"
let profilePictureUrl = NSURL(string: userProfile)
let profilePictureData = NSData(contentsOf: profilePictureUrl! as URL)
if(profilePictureData != nil)
{
let avaFile = PFFile(data:profilePictureData! as Data)
user["ava"] = avaFile
}
// will try to login with facebook
user.signUpInBackground { (success, error) -> Void in
if success
{
// remember looged user
UserDefaults.standard.set(user.username, forKey: "username")
UserDefaults.standard.set(true, forKey: "byFacebook")
// call login func from AppDelegate.swift class
let appDelegate : AppDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.login()
self.setUp.isHidden = true
self.indicator.isHidden = true
self.indicator.stopAnimating()
}
else
{
let existing : String? = UserDefaults.standard.string(forKey: "username")
// user already exists in app database
PFUser.logInWithUsername(inBackground: existing!, password: user.password!){ (user, error) -> Void in
if error == nil
{
// remember user or save in App Memory did the user login or not
UserDefaults.standard.set(user!.username, forKey: "username")
UserDefaults.standard.set(true, forKey: "byFacebook")
// call login function from AppDelegate.swift class
let appDelegate : AppDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.login()
self.setUp.isHidden = true
self.indicator.isHidden = true
self.indicator.stopAnimating()
}
}
}
}
})
}
else
{
self.setUp.isHidden = true
self.indicator.isHidden = true
self.indicator.stopAnimating()
}
}
}