保存电子邮件地址 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 登录 - 保存输入的用户名和电子邮件