解析 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.currentUser() 执行自动 segue