我正在使用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()
分配当前用户对象(例如,通过不在后台线程中加载用户)?
非常感谢所有帮助!
编辑:我已经使用更多代码更新了这篇文章,以帮助突出显示我可能遗漏的任何错误。
答案 0 :(得分:3)
我发现出现此问题是因为segue signInToNavigation
是从Login-button连接的,而不是从登录视图控制器本身连接的。这导致segue在执行登录功能之前执行,因此在加载表视图时尚未分配PFUser.currentUser()
对象。我通过重新布线来解决这个问题。愚蠢的滑倒在我身边。
感谢Ryan Kreager和Wain花时间帮我解决这个问题!
答案 1 :(得分:0)
您可以尝试检查是否PFUser.currentUser() != nil
,以确保在登录后立即设置它。如果它没有立即设置,你知道有更深层次的登录问题。
另外,尝试删除对segue的调用的dispatch_async(dispatch_get_main_queue()){
包装器。
这是不必要的(logInWithUsernameInBackground已经返回到主线程)并且我有一种预感,它正在创建一个不首先设置本地对象的竞速条件,因为Parse因为你要去的时候不能进行任何调用后的清理正确的主线。