所以我尝试使用Parse + Facebook登录我的应用程序,但是在保存用户的实际姓名/电子邮件地址时遇到了困难。我现在只使用Facebook身份验证,现在我的用户可以登录/ reigster,但它将用户名存储为编码字符串(即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
}
})
}
}
}
}
答案 0 :(得分:1)
用户登录以便您使用Facebook API的登录屏幕不会为您提供用户的电子邮件。它会为您提供一个访问令牌,即您所看到的6zAhVeAklzyKnA5weq29
。除非您创建自定义Web视图,否则您将无法存储用户的电子邮件。但是,您可以将访问令牌存储在NSUserDefaults或Parse案例中(我建议只使用NSUserDefaults,因为它更容易)并使用它来从Facebook API进行调用。