保存电子邮件地址 Facebook + Parse (Swift)

Posted

技术标签:

【中文标题】保存电子邮件地址 Facebook + Parse (Swift)【英文标题】:saving email address Facebook + Parse (Swift) 【发布时间】:2015-07-14 00:21:40 【问题描述】:

所以我尝试使用 Parse + Facebook 让人们登录到我的应用程序,但在保存用户的实际姓名/电子邮件地址时遇到了困难。我现在只使用 Facebook 身份验证,我现在的用户可以登录/重新注册,但它将用户名存储为编码字符串(即 6zAhVeAklzyKnA5weq29)而不是实际名称。此外,没有存储电子邮件地址(我正在使用 Parse 默认“用户”表)。

这是我的代码

主视图控制器:

class homeViewController: UIViewController, PFLogInViewControllerDelegate, PFSignUpViewControllerDelegate 
    @IBOutlet weak var nameLabel: UILabel!

var noteObjects: NSMutableArray! = NSMutableArray()
let permissions = ["public_profile", "email"]

override func viewDidLoad() 
    super.viewDidLoad()        
    Utils.logInWithFacebook()


override func viewDidAppear(animated: Bool) 
    super.viewDidAppear(animated)

    if (PFUser.currentUser() == nil) 

       // Utils.logInWithFacebook()
        let logInViewController = MyLogInViewController()
        logInViewController.signUpController = PFSignUpViewController()
        //self.presentViewController(logInViewController, animated: true, completion: nil)

        logInViewController.fields = PFLogInFields.Facebook

        logInViewController.delegate = self

        var signUpViewController = PFSignUpViewController()

        signUpViewController.delegate = self

        logInViewController.signUpController = signUpViewController

        self.presentViewController(logInViewController, animated: true, completion: nil)

    else 
       //  Utils.logInWithFacebook()
        var username = PFUser.currentUser().username
        nameLabel.text = username
        self.fetchAllObjectsFromLocalDatastore()
        self.fetchAllObjects()
    



func fetchAllObjectsFromLocalDatastore() 

    var query: PFQuery = PFQuery(className: "Note")

    query.fromLocalDatastore()
    query.whereKey("username", equalTo: PFUser.currentUser().username)
    query.findObjectsInBackgroundWithBlock  (objects, error) -> Void in

        if (error == nil) 
            var temp: NSArray = objects as NSArray
            self.noteObjects = temp.mutableCopy() as! NSMutableArray
            //                self.tableView.reloadData()
        else 
            println(error.userInfo)
        
    


func fetchAllObjects() 

    PFObject.unpinAllObjectsInBackgroundWithBlock(nil)

    var query: PFQuery = PFQuery(className: "Note")
    query.whereKey("username", equalTo: PFUser.currentUser().username)
    query.findObjectsInBackgroundWithBlock  (objects, error) -> Void in
        if (error == nil) 
            PFObject.pinAllInBackground(objects, block: nil)
            self.fetchAllObjectsFromLocalDatastore()
        else 
            println(error.userInfo)
        
    

func logInViewController(logInController: PFLogInViewController!, shouldBeginLogInWithUsername username: String!, password: String!) -> Bool 

    if (!username.isEmpty || !password.isEmpty) 
        return true
    else 
        return false
    


func logInViewController(logInController: PFLogInViewController!, didLogInUser user: PFUser!) 
    self.dismissViewControllerAnimated(true, completion: nil)


func logInViewController(logInController: PFLogInViewController!, didFailToLogInWithError error: NSError!) 
    println("Failed to log in...")


func signUpViewController(signUpController: PFSignUpViewController!, shouldBeginSignUp info: [NSObject : AnyObject]!) -> Bool 
    if let password = info?["password"] as? String 
        // return password.utf16Count >= 8
        return count(password.utf16) >= 8
     else 
        return false
    


func signUpViewController(signUpController: PFSignUpViewController!, didSignUpUser user: PFUser!) 
    self.dismissViewControllerAnimated(true, completion: nil)


func signUpViewController(signUpController: PFSignUpViewController!, didFailToSignUpWithError error: NSError!) 
    println("Failed to sign up...")


func signUpViewControllerDidCancelSignUp(signUpController: PFSignUpViewController!) 
    println("User dismissed sign up.")


override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.


// MARK: - Table view data source

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 

    //var upcoming: AddNoteTableViewController = segue.destinationViewController as! AddNoteTableViewController
    if (segue.identifier == "editNote") 

    
 

我有 Facebook 登录代码的 Utils 类

import Foundation

class Utils 

 class func notLoggedIn() -> Bool 
    let user = PFUser.currentUser()
    // here I assume that a user must be linked to Facebook
    return user == nil || !PFFacebookUtils.isLinkedWithUser(user)

class func loggedIn() -> Bool 
    return !notLoggedIn()



class func logInWithFacebook() 
    PFFacebookUtils.logInWithPermissions(["public_profile", "user_friends", "email"]) 
        (user: PFUser!, error: NSError!) -> Void in
        if user == nil 
            NSLog("The user cancelled the Facebook login (user is nil)")
         else 
            NSLog("The user successfully logged in with Facebook (user is NOT nil)")
            // HERE I SET AN ACL TO THE INSTALLATION
            if let installation = PFInstallation.currentInstallation() 
                let acl = PFACL(user: PFUser.currentUser()) // Only user can write
                acl.setPublicReadAccess(true) // Everybody can read
                acl.setWriteAccess(true, forRoleWithName: "Admin") // Also Admins can write
                installation.ACL = acl
                //installation.saveEventually()
            
            // THEN I GET THE USERNAME AND fbId
            Utils.obtainUserNameAndFbId()
        
    



class func obtainUserNameAndFbId() 
    if notLoggedIn() 
        return
    
    let user = PFUser.currentUser() // Won't be nil because is logged in
    // RETURN IF WE ALREADY HAVE A USERNAME AND FBID (note that we check the fbId because Parse automatically fills in the username with random numbers)
    if let fbId = user["fbId"] as? String 
        if !fbId.isEmpty 
            println("we already have a username and fbId -> return")
            return
        
    
    // REQUEST TO FACEBOOK
    println("performing request to FB for username and IDF...")
    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 :)")
                    println(result)
                    // You have 2 ways to access the result:
                    // 1)
                    println(result["name"])
                    println(result["id"])
                    println(result["email"])
                    // 2)
                    println(result.name)
                    println(result.objectID)
                    println(result.email)
                    // Save to Parse:
                    PFUser.currentUser().username = result.email
                    PFUser.currentUser().email = result.email
                    PFUser.currentUser().setValue(result.objectID, forKey: "fbId")
                    PFUser.currentUser().setValue(result.email, forKey: "email")

                    //PFUser.currentUser().saveEventually()
                    // Always use saveEventually if you want to be sure that the save will succeed
                
            )
        
    



【问题讨论】:

【参考方案1】:

用户登录以供您使用 Facebook API 的登录屏幕不会向您提供用户的电子邮件。相反,它会为您提供一个访问令牌,即您所看到的6zAhVeAklzyKnA5weq29。除非您创建自定义 Web 视图,否则您将无法存储用户的电子邮件。但是,您可以将访问令牌存储在 NSUserDefaults 或在您的情况下 Parse(我建议只使用 NSUserDefaults,因为它更容易)并使用它从 Facebook API 进行调用。

【讨论】:

以上是关于保存电子邮件地址 Facebook + Parse (Swift)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Parse.com 登录获取 Facebook 用户电子邮件

在 Parse 中使用 FBgraphUser 从 Facebook 获取用户电子邮件

解析 Facebook 登录 - 保存输入的用户名和电子邮件

Facebook 登录 - 获取用户数据

在 iOS9 和 Swift2 中使用 Parse 登录 Facebook

无法使用 Parse 搜索新的 facebook auth 用户