我一直在努力在swift中创建一个facebook登录/注册功能。我一直在寻找一个教程,但一直找不到任何东西。所以我一直在尝试自己做。它似乎工作,但为什么它不保存我的facebookName,性别和图像在数据库中?它将它保存在模拟器中但不是在我使用我的ios 8设备时?
我收到此日志消息“用户注册并通过Facebook登录!”,并且新用户被添加到解析类,但不是名称,图像和性别......
@IBAction func login(sender: UIButton!) {
var permissionArray = ["user_about_me", "user_relationships", "user_birthday", "user_location"]
PFFacebookUtils.initializeFacebook()
PFFacebookUtils.logInWithPermissions(permissionArray, block: { (user: PFUser!, error: NSError!) in
println(user)
if user == nil {
println(error.localizedDescription)
} else {
if user.isNew {
var userQuery = PFUser.query()
userQuery.getObjectInBackgroundWithId(PFUser.currentUser().objectId) {
(userObject: PFObject!, error: NSError!) -> Void in
var fbRequest = FBRequest.requestForMe()
fbRequest.startWithCompletionHandler { (connection: FBRequestConnection!, result:AnyObject!, error: NSError!) in
if error == nil {
//FACEBOOK DATA IN DICTIONARY
var userData = result as NSDictionary
var faceBookId = userData.objectForKey("id") as NSString
var faceBookName = userData.objectForKey("first_name") as NSString
var faceBookMiddle = userData.objectForKey("middle_name") as NSString
var faceBookGender = userData.objectForKey("gender") as NSString
var url:NSURL = NSURL.URLWithString(NSString(format:"https://graph.facebook.com/%@/picture?width=320", faceBookId))
var err: NSError?
var imageData :NSData = NSData.dataWithContentsOfURL(url, options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &err)
var imageFile = PFFile(name: "image.jpg", data: imageData) as PFFile
println(userData)
userObject.setObject(faceBookName, forKey: "name")
userObject.setObject(imageFile, forKey: "file")
userObject.setObject(faceBookGender, forKey: "gender")
userObject.saveInBackground()
var sharedInstance:userSingleton = userSingleton.sharedInstance
sharedInstance.userName = (userObject.objectForKey("name") as NSString)
sharedInstance.userGender = (userObject.objectForKey("gender") as NSString)
(userObject.objectForKey("file") as PFFile).getDataInBackgroundWithBlock {
(theImageData: NSData!, error: NSError!) -> Void in
println(error)
if error == nil {
sharedInstance.userImage = UIImage(data:theImageData)
}
self.performSegueWithIdentifier("LoginSegue", sender: self)
}
}
}
}
println("User signed up and logged in through Facebook!")
} else {
println("User logged in through Facebook!")
}
}
})
}
}
答案 0 :(得分:4)
假设您使用Parse,这里我是如何做的。我个人创建了一个类 Utils.swift ,在那里我把我想要重用的所有内容(或者我不希望在我的ViewControllers中使用):
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"]) {
(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 A USER POINTER TO THE INSTALLATION
// That way we can send push notifications to specific users
if let installation = PFInstallation.currentInstallation() {
installation["user"] = PFUser.currentUser()
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"])
// 2)
println(result.name)
println(result.objectID)
// Save to Parse:
PFUser.currentUser().username = result.name
PFUser.currentUser().setValue(result.objectID, forKey: "fbId")
PFUser.currentUser().saveEventually() // Always use saveEventually if you want to be sure that the save will succeed
}
})
}
}
}
}
然后,当您想要执行登录时,只需拨打Utils.logInWithFacebook()
即可。
请注意,由于facebook me请求可能失败,因此无法保证您将用户名和Facebook ID成功保存到Parse。这就是为什么我创建方法Utils.obtainUserNameAndFbId()
,我在application(_: didFinishLaunchingWithOptions)
中调用它(它可以在每次启动时调用,因为它只会在FB成功之前执行请求)。