简体   繁体   中英

iOS How to fetch user photo from Facebook use parse swift 4

I have issues with loading user photo from facebook.

I want to fetch facebook user photo to parse data base.

My code:

let permissions:[String] = ["public_profile", "email"]
    PFFacebookUtils.logInInBackground(withReadPermissions: permissions) { (user, error) 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!")
            self.loadData()
        } else {
            NSLog("User logged in through Facebook!")

        }
    }

func loadData(){
    let fbRequest = FBSDKGraphRequest(graphPath: "me", parameters: nil)
    fbRequest?.start(completionHandler: { (FBSDKGraphRequestConnection, result, error) in
        if error == nil{
            if let dict = result as? Dictionary<String, AnyObject>{
                let name:String = dict["name"] as AnyObject? as! String
                let facebookID:String = dict["id"] as AnyObject? as! String
                let email:String = dict["email"] as AnyObject? as! String

                let pictureURL = "https://graph.facebook.com/\(facebookID)/picture?type=large&return_ssl_resources=1"

                let URLRequest = NSURL(string: pictureURL)
                let URLRequestNeeded = NSURLRequest(url: URLRequest! as URL)



                NSURLConnection.sendAsynchronousRequest(URLRequestNeeded as URLRequest, queue: OperationQueue.main, completionHandler: { (response, data, error) in
                        if error == nil {
                            let picture = PFFile(data: data!)
                            PFUser.current()?.setObject(picture!, forKey: "profilePicture")
                            PFUser.current()?.saveInBackground()
                        }
                        else {
                            print("Error: \(String(describing: error?.localizedDescription))")
                        }
                    })


                PFUser.current()!.setValue(name, forKey: "username")
                PFUser.current()!.setValue(email, forKey: "email")
                PFUser.current()!.saveInBackground()
            }
        }
    })

}

But i all time i have error message, and in data base i have empty row.

How i can fix it?

you can try

    @IBAction func loginFacebookAction(sender: AnyObject) {//action of the custom button in the storyboard
        let fbLoginManager : FBSDKLoginManager = FBSDKLoginManager()
        fbLoginManager.logIn(withReadPermissions: ["email"], from: self) { (result, error) -> Void in
            if (error == nil){
                let fbloginresult : FBSDKLoginManagerLoginResult = result!
                // if user cancel the login
                if (result?.isCancelled)!{
                    return
                }
                if(fbloginresult.grantedPermissions.contains("email"))
                {
                    self.getFBUserData()
                }
            }else {
                print(error!.localizedDescription)
//                self.view.showToast(withMessage: error!.localizedDescription)
            }
        }
    }

    func getFBUserData(){
        if((FBSDKAccessToken.current()) != nil){
            FBSDKGraphRequest(graphPath: "me", parameters: ["fields": "id, name, first_name, last_name, picture.type(large), email"]).start(completionHandler: { (connection, result, error) -> Void in
                if (error == nil){
                    //everything works print the user data
                    print(result)
//                    if let data = result as? [String:Any],
//                        let user = Mapper<User>().map(
//                            JSONObject: data
//                        ){
//                        AppHelper.set(currentuser: user)
//                    }
                }else {
//                    self.view.showToast(withMessage: error!.localizedDescription)
                    print(error!.localizedDescription)
                }
            })
        }
    }

After trying many methods, this is what works for me.

On AppDelegate, import Parse, ParseFacebookUtilsV4 and FBSDKCoreKit

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
{
    PFFacebookUtils.initializeFacebook(applicationLaunchOptions: launchOptions)
    FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions) 
return true
}

and add two methods

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)
}

And then, on login 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()
        }


    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM