解析PFUser.currentUser返回nil - Swift

时间:2015-07-20 16:57:27

标签: ios swift login parse-platform

我正在使用Parse登录我的用户。当我的应用程序打开时,我的LaunchVieWController确定用户是否已登录:

override func viewDidLoad() {
    super.viewDidLoad()

    //Make sure cached users don't have to log in every time they open the app
    var currentUser = PFUser.currentUser()
    println(currentUser)
    if currentUser != nil {
        dispatch_async(dispatch_get_main_queue()) {
            self.performSegueWithIdentifier("alreadySignedIn", sender: self)
        }
    } else {
        dispatch_async(dispatch_get_main_queue()) {
            self.performSegueWithIdentifier("showSignUpIn", sender: self)
        }
    }
}

如果用户已登录,则会将其带到下面描述的表格视图中。如果他们未登录,则会将他们带到可以转到注册视图或登录视图的视图中。

我的注册工作完全正常,并注册用户,然后将其重定向到表格视图。 这是注册功能(它与登录功能位于一个单独的控制器中):

func processSignUp() {

    var userEmailAddress = emailAddress.text
    var userPassword = password.text

    // Ensure username is lowercase
    userEmailAddress = userEmailAddress.lowercaseString

    // Add email address validation

    // Start activity indicator
    activityIndicator.hidden = false
    activityIndicator.startAnimating()

    // Create the user
    var user = PFUser()
    user.username = userEmailAddress
    user.password = userPassword
    user.email = userEmailAddress

    user.signUpInBackgroundWithBlock {
        (succeeded: Bool, error: NSError?) -> Void in
        if error == nil {

            dispatch_async(dispatch_get_main_queue()) {
                self.performSegueWithIdentifier("signInToNavigation", sender: self)
            }

        } else {

            self.activityIndicator.stopAnimating()

            if let message: AnyObject = error!.userInfo!["error"] {
                self.message.text = "\(message)"
            }               
        }
    }
}

我的登录功能如下:

@IBAction func signIn(sender: AnyObject) {
    var userEmailAddress = emailAddress.text
    userEmailAddress = userEmailAddress.lowercaseString
    var userPassword = password.text

   PFUser.logInWithUsernameInBackground(userEmailAddress, password:userPassword) {
        (user: PFUser?, error: NSError?) -> Void in
        if user != nil {
            dispatch_async(dispatch_get_main_queue()) {
                self.performSegueWithIdentifier("signInToNavigation", sender: self)
            }
        } else {
            if let message: AnyObject = error!.userInfo!["error"] {
                self.message.text = "\(message)"
            }
        }
    }
}

用户登录后,会将其发送到表格视图。在该表视图中,我试图访问以下函数中的当前用户对象,因为我想根据用户是谁加载不同的数据:

override func queryForTable() -> PFQuery {
    var query = PFQuery(className:"MyClass")
    query.whereKey("userID", equalTo: PFUser.currentUser()!)
    return query
}

当我尝试使用用户登录时,我会抛出以下错误:"致命错误:在解开可选值"时意外发现nil。似乎PFUser.currentUser()对象是零。

注册后将用户发送到表格视图时,PFUser.currentUser()对象已设置并且运行正常。

我的猜测是,这是因为PFUser.logInWithUsernameInBackground发生在后台并且我的查询在加载之前尝试获取PFUser.currentUser()对象。无论如何我可以解决这个问题吗?在表视图中,加载表数据需要PFUser.currentUser()的值。我可以以某种方式确保在调用函数之前为PFUser.currentUser()分配当前用户对象(例如,通过不在后台线程中加载用户)?

非常感谢所有帮助!

编辑:我已经使用更多代码更新了这篇文章,以帮助突出显示我可能遗漏的任何错误。

2 个答案:

答案 0 :(得分:3)

我发现出现此问题是因为s​​egue signInToNavigation是从Login-button连接的,而不是从登录视图控制器本身连接的。这导致segue在执行登录功能之前执行,因此在加载表视图时尚未分配PFUser.currentUser()对象。我通过重新布线来解决这个问题。愚蠢的滑倒在我身边。

感谢Ryan Kreager和Wain花时间帮我解决这个问题!

答案 1 :(得分:0)

您可以尝试检查是否PFUser.currentUser() != nil,以确保在登录后立即设置它。如果它没有立即设置,你知道有更深层次的登录问题。

另外,尝试删除对segue的调用的dispatch_async(dispatch_get_main_queue()){包装器。

这是不必要的(logInWithUsernameInBackground已经返回到主线程)并且我有一种预感,它正在创建一个不首先设置本地对象的竞速条件,因为Parse因为你要去的时候不能进行任何调用后的清理正确的主线。