无法使用 Swift 在 Xcode 中使用 Parse 1.7.2 和 Facebook SDK 4.1 创建新用户
Posted
技术标签:
【中文标题】无法使用 Swift 在 Xcode 中使用 Parse 1.7.2 和 Facebook SDK 4.1 创建新用户【英文标题】:Can't create new user using Parse 1.7.2 and Facebook SDK 4.1 in Xcode using Swift 【发布时间】:2015-05-16 20:37:29 【问题描述】:我已将我的应用程序链接到 Facebook SDK 和 Parse,但现在我正在尝试将 Facebook 的登录信息与 Parse 集成,但一直遇到问题。我当前的问题是应用程序运行,但是当我按下 FBSDKLoginButton 时,它会进入 safari 并请求权限(应该如此),但是当按下确定时,它只是返回到应用程序的登录屏幕,就像什么都没发生一样不要对应用程序的其余部分执行 segue。我还检查了 Parse,它没有创建新的 PFUser。我将在下面发布我认为可能与我的 LoginViewController 相关的代码(这意味着代码将缺少像我的 viewDidLoad 这样的部分,因为它没有任何影响登录过程的内容):
import UIKit
import Parse
import FBSDKCoreKit
import FBSDKLoginKit
protocol LoginViewControllerDelegate
func onRegister(loginViewController : LoginViewController)
func onFacebookLogin(loginViewController : LoginViewController)
func onLogin(loginViewController : LoginViewController)
class LoginViewController: UIViewController
@IBAction func onFacebookLogin(sender: AnyObject?)
// Set permissions required from the facebook user account
let permissions = [ "user_about_me", "user_relationships", "user_location", "user_birthday", "public_profile", "user_friends", "user_email", "user_gender"]
// Login PFUser using Facebook
PFFacebookUtils.logInInBackgroundWithReadPermissions(permissions, block:
(user: PFUser?, error: NSError?) -> Void in
if let user = user
if user.isNew
println("User signed up and logged in through Facebook!")
self.loadData()
self.performSegueWithIdentifier("loggedIn", sender: self)
else
println("User logged in through Facebook!")
self.performSegueWithIdentifier("loggedIn", sender: self)
if self.delegate != nil
self.delegate!.onFacebookLogin(self)
else
println("Uh oh. The user cancelled the Facebook login.")
)
func loadData()
let request:FBSDKGraphRequest = FBSDKGraphRequest()
request.startWithCompletionHandler (connection:FBSDKGraphRequestConnection!, result:AnyObject!, error:NSError!) -> Void in
if error == nil
if let dict = result as? Dictionary<String, AnyObject>
let name:String = dict["first_name"] as AnyObject? as! String
let facebookID:String = dict["id"] as AnyObject? as! String
let email:String = dict["email"] as AnyObject? as! String
let birthday:String = dict["birthday"] as AnyObject? as! String
let gender:String = dict["gender"] as AnyObject? as! String
let hostCount:Int = 0
let attendCount:Int = 0
let pictureURL = "https://graph.facebook.com/\(facebookID)/picture?type=large&return_ssl_resources=1"
var URLRequest = NSURL(string: pictureURL)
var URLRequestNeeded = NSURLRequest(URL: URLRequest!)
NSURLConnection.sendAsynchronousRequest(URLRequestNeeded, queue: NSOperationQueue.mainQueue(), completionHandler: (response: NSURLResponse!,data: NSData!, error: NSError!) -> Void in
if error == nil
var picture = PFFile(data: data)
PFUser.currentUser()!.setObject(picture, forKey: "profilePicture")
PFUser.currentUser()!.saveInBackground()
else
println("Error: \(error.localizedDescription)")
)
PFUser.currentUser()!.setValue(name, forKey: "name")
PFUser.currentUser()!.setValue(email, forKey: "email")
PFUser.currentUser()!.setValue(birthday, forKey: "birthday")
PFUser.currentUser()!.setValue(gender, forKey: "gender")
PFUser.currentUser()!.setValue(hostCount, forKey: "hostCount")
PFUser.currentUser()!.saveInBackground()
【问题讨论】:
【参考方案1】:我使用此解决方案,希望对您有所帮助。如果你有任何问题,我可以回答:)
func notLoggedIn() -> Bool
let user = PFUser.currentUser()
// here I assume that a user must be linked to Facebook
return user == nil || !PFFacebookUtils.isLinkedWithUser(user)
func loggedIn() -> Bool
return !notLoggedIn()
func performNewUser()
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
displayAlert("Erreur", error: "Il existe déjà un utilisateur avec ce compte Facebook")
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)
println(result.name)
println(result.objectID)
// Save to Parse:
var FBSession = PFFacebookUtils.session()
var currentUser = PFUser.currentUser()
var userToSave = PFObject(className: "Utilisateurs")
var accessToken = FBSession.accessTokenData.accessToken
let url = NSURL(string: "https://graph.facebook.com/me/picture?type=large&return_ssl_resources=1&access_token="+accessToken)
let urlRequest = NSURLRequest(URL: url!)
NSURLConnection.sendAsynchronousRequest(urlRequest, queue: NSOperationQueue.mainQueue(), completionHandler:
response, data, error in
let image = UIImage(data: data)
currentUser["image"] = data
currentUser.save()
self.performSegueWithIdentifier("connexionApplicationInscriptionViaFacebook", sender: self)
)
let firstName = result["first_name"] as String
let status = "Client"
currentUser.username = result["last_name"] as String
currentUser.email = result.email
userToSave.setObject(currentUser.username, forKey: "nom")
userToSave.setObject(currentUser.username, forKey: "username")
userToSave.setObject(firstName, forKey: "prenom")
userToSave.setObject(status, forKey: "status")
currentUser.setValue(self.tfPrenom.text, forKey: "name")
currentUser.setValue(result.objectID, forKey: "fbId")
currentUser.saveEventually() // Always use saveEventually if you want to be sure that the save will succeed
)
【讨论】:
感谢您的帮助,伯特兰!我刚刚尝试了这种方法,但出现了两个错误:一个在“if let fbId = user["fbId"] as?String " 声明“'String?'不能转换为“StringLiteralConvertible””。另一个错误与“if let session = PFFacebookUtils.session() ”有关,其中指出“'PFFacebookUtils.Type' 没有名为'session'的成员” 您是否使用最新版本的 Parse 和 Facebook SDK? 啊!我正在使用 Xcode 6.2 和 parse 1.6.4,旧版本的 parse,很抱歉,我没有看到您使用的是最新版本:/ 对于第一个错误,它似乎是转换为字符串的演变,也许你必须像这样声明 fbid:var fbid:String = "" 而对于“session”,它是一个公共 api在 PFFacebookUtils.h : ( /*!@abstract 获取当前用户的 Facebook 会话。*/ + (PF_NULLABLE FBSession *)session; ) 非常感谢您的帮助!您是否在 IBAction 中为 UIButton 或 FBSDKLoginButton 使用了它?【参考方案2】:在更新到 Parse 1.7.4 并删除旧的 PFFacebookUtils 框架(保留 PFFacebookUtilsV4)之后似乎已经自行解决了问题!我希望这个答案可以帮助其他有同样问题的人。
【讨论】:
以上是关于无法使用 Swift 在 Xcode 中使用 Parse 1.7.2 和 Facebook SDK 4.1 创建新用户的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 Xcode 8 和 Swift 3 在 SpriteKit 中以编程方式触发 segue
无法使用 Swift 在 Xcode 中使用 Parse 1.7.2 和 Facebook SDK 4.1 创建新用户
无法在 Alamofire 中禁用缓存(Xcode 9 - swift 4)