无法使用 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 Swift 项目中执行“快速测试”

无法使用 Xcode 8 和 Swift 3 在 SpriteKit 中以编程方式触发 segue

无法使用 Swift 在 Xcode 中使用 Parse 1.7.2 和 Facebook SDK 4.1 创建新用户

无法在 Alamofire 中禁用缓存(Xcode 9 - swift 4)

无法使用 Swift 2 在 Xcode 7 beta 中导入 FBSDK

swift:Xcode无法为Facebook框架生成Swift表示