在执行下一段代码(推送到故事板)之前,我需要完成“getUserInfo”。目前,当故事板推送执行时,“getUserInfo”仍在进行中。如何按顺序执行这些操作?我需要将这两个函数分开,所以将代码放在loginUser的完成处理程序中并不是一个好的解决方案。非常感谢那些比我更聪明的人:)
func loginUser() {
PFUser.logInWithUsernameInBackground(txtEmailAddress.text, password:txtPassword.text) {
(user: PFUser?, error: NSError?) -> Void in
if user != nil {
// Successful login.
self.txtPassword.resignFirstResponder()
self.txtEmailAddress.resignFirstResponder()
getUserInfo()
// Push to Main.storyboard.
let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
let viewController: AnyObject = storyboard.instantiateInitialViewController()
self.presentViewController(viewController as! UIViewController, animated: true, completion: nil)
} else {
// The login failed. Display alert.
self.displayAlert("Error", message: "Login incorrect")
}
}
}
func getUserInfo() {
let currentUser = PFUser.currentUser()
let userQuery = PFQuery(className: "_User")
userQuery.whereKey("username", equalTo: PFUser.currentUser()!.username!)
userQuery.findObjectsInBackgroundWithBlock({ (results:[AnyObject]?, error:NSError?) -> Void in
if error == nil {
for result in results! {
userType = result["userType"] as! String
if userType == "admin" {
user = "AdminSetting"
} else {
user = "StandardSetting"
}
}
}
})
}
答案 0 :(得分:0)
您要做的是使异步函数(具有完成处理程序的函数)同步,以便它立即返回。然而,这通常是一个坏主意,因为如果执行在主线程中停止,则用户无法执行任何操作,并且您的应用程序将停滞不前,直到代码再次继续。这可能需要几秒钟,具体取决于连接,这不是很好,您应该在异步任务上真正更新UI异步。通常没有充分理由做这样的事情,如果你有这样的话,你可以告诉我。
答案 1 :(得分:0)
您还可以在getUserInfo()中执行故事板代码,作为作为参数传入的块/闭包。这样,您可以确保在getUserInfo中的异步调用完成时执行
答案 2 :(得分:0)
Shadowman建议的是正确/最优雅的解决方案。
以下是一个例子:
func getUserInfo(completion: (results:[AnyObject]?, error:NSError?) -> Void) {
let currentUser = PFUser.currentUser()
let userQuery = PFQuery(className: "_User")
userQuery.whereKey("username", equalTo: PFUser.currentUser()!.username!)
userQuery.findObjectsInBackgroundWithBlock(completion)
}
通过这种方式,您可以在完成后从电话中取回实际结果,方便,嗯?
以下是您的称呼方式:
self.getUserInfo { (results, error) -> Void in
// Here the results are already fetched, so proceed with your
// logic (show next controller or whatever...)
if error == nil {
for result in results! {
userType = result["userType"] as! String
if userType == "admin" {
user = "AdminSetting"
} else {
user = "StandardSetting"
}
}
}
// depending on whether this will still run in a background thread, you might have to dispatch this code to the main thread.
// you can check whether this code block is called on the main thread
// by checking if NSThread.isMainThread() returns true
// if not, you will need to use this dispatch block!
dispatch_async(dispatch_get_main_queue(), { () -> Void in
// only call UI code in main thread!
// MOVE TO NEXT controller in here!
})
}