解析 PFUser.currentUser 返回 nil - Swift

Posted

技术标签:

【中文标题】解析 PFUser.currentUser 返回 nil - Swift【英文标题】:Parse PFUser.currentUser returns nil - Swift 【发布时间】:2015-07-20 16:57:27 【问题描述】:

我正在使用 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() 分配了当前用户对象(例如,通过不在后台线程中加载用户)?

非常感谢所有帮助!

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

【问题讨论】:

你是否测试过它是否在登录响应处理程序之前被调用? 我不完全确定如何对此进行测试,但我在这里添加了一个断点:i.imgur.com/cYZLtNj.png 并且错误仍然存​​在(它不会在断点处停止,但会抛出相同的表视图中的错误)。这看起来很奇怪,因为我认为signInToNavigation segue 必须在该视图中的任何代码执行之前执行。 它会,除非有不同的方法来实现它。在这个阶段,日志记录可能比断点更好 我已经用更多(希望是)相关代码更新了我的帖子。当我注册用户时,PFUser.currenUser 对象被设置并且一切正常。无法理解为什么这不适用于登录功能。 您真的应该使用if let user = user 而不是if user != nil 的形式来检查用户是否可用,但除此之外我看不出有什么问题。您是否在登录响应中记录了返回的用户和​​错误? 【参考方案1】:

我发现出现这个问题是因为 segue signInToNavigation 是从登录按钮连接的,而不是从登录视图控制器本身连接的。这导致在执行登录功能之前执行 segue,因此在加载表视图时尚未分配 PFUser.currentUser()object。我通过重新布线解决了这个问题。愚蠢的失误在我这边。

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

【讨论】:

嘘!很高兴你明白了:)【参考方案2】:

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

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

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

【讨论】:

感谢您的回答!如果我删除 dispatch_async(dispatch_get_main_queue()),仍然会抛出错误 (fatal error: unexpectedly found nil while unwrapping an Optional value)。 我已经用更多(希望是)相关代码更新了我的帖子。当我注册用户时,PFUser.currenUser 对象被设置并且一切正常。无法理解为什么这不适用于登录功能。 我会测试一下,看看能不能找到bug! 更新了我的答案 - 除了检查 if user != nil 之外,尝试检查 PFUser.currentUser() != nil 以确保它在登录后立即设置。 发现问题。感谢您的帮助!

以上是关于解析 PFUser.currentUser 返回 nil - Swift的主要内容,如果未能解决你的问题,请参考以下文章

为啥不解析在注销时重置 PFuser?

解析传递 PFUser 到 Watch 扩展

在应用启动时使用 PFUser.currentUser() 执行自动 segue

FB登录后解析会话令牌无效

Parse.com 查询 PFUser CurrentUser

iOS - 解析当前用户获取不起作用