我想做什么:我有一个登录屏幕,用户填写用户名和密码,然后按下登录按钮。完成对服务器的异步调用以检查用户是否已注册且密码是否正常,如果是(异步功能将bool设置为yes),则对下一个视图控制器执行segue。很简单,我尝试了很多方法,但总是遇到同样的问题,主线程运行shouldPerformSegueWithIdentifier
方法,执行异步调用并在后台线程之前检查全局bool var(默认为false)已更新它,因此不执行segue,因为全局变量设置为true AFTER。只有当我使用sleep(1)时,UI才会刷新,但我不想使用它。有没有办法在没有睡觉的情况下做到这一点?我运行的每个方法都有一个完成处理程序
我不知道如何将主要与后台线程同步。我已经读过它可以从异步调用更新UI,所以这应该是可行的。我已经找了一段时间的问题并尝试了很多代码片段,但仍然没有找到解决我问题的方法。
这是我到目前为止的代码:
override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool {
let apiCall = webApi()
dispatch_async(dispatch_get_main_queue()) {
apiCall.callCheckIsUserLogged(nil, password : self.passwordField.text, email: self.mailField.text){ (ok) in
}
}
//sleep(1) if I uncomment this, my method works because it will return true
return userIsLogged
}
apiCall.callCheckIsUserLogged()
:
typealias successClosure = (success : Bool) -> Void
//Make a call to check if the user exist, server returns json with success or failure
func callCheckIsUserLogged(username: String?, password : String?, email: String?,completed : successClosure){
userApiCallUrl = "http://apiurl.com/users/login"
let call = asyncCallClass()
call.doAsyncCallWithParams(userApiCallUrl, calltype: "POST", username: username, pass: password, mail: email){ (success) in
completed(success: true)
}
}
call.doAsyncCallWithParams()
代码:
internal typealias completion = (success : Bool) -> Void
private var flagCompletion : Bool = false
//Handle async class with this method
//var callType is aditioned everytime an arg is not passed nil.
//callType == 3 it is a call to check if user is logged
//callType == 2 is a call to register a new user
func doAsyncCallWithParams(url : String, calltype : String, username : String?, pass : String?, mail : String?, completed : completion){
var callType : Int = 0
//Set Async Url
setUrl(url)
//Set Post Params
if let user : String = username{
self.username = "username=\(user)"
callType += 1
}
if let password : String = pass{
self.password = "password=\(password)"
callType += 1
}
if let mail : String = mail{
self.email = "email=\(mail)"
callType += 1
}
//register a new user
if(callType == 3){
paramString = "\(self.username)&\(self.password)&\(self.email)"
}
//check if user is logged, send email and password
if(callType == 2){
paramString = "\(self.email)&\(self.password)"
}
//Do call
callWithCompletionHandler { (success) in
self.flagCompletion = true
completed(success: self.flagCompletion)
}
}
callWithCompletionHandler()
代码:
private typealias completionAsyncCall = (success : Bool) -> Void
private func callWithCompletionHandler(completed : completionAsyncCall){
asyncJson.removeAllObjects()
//Set async call params
let request = NSMutableURLRequest(URL: NSURL(string: self.url!)!)
request.HTTPMethod = "POST"
let trimmedPostParam : String = self.paramString!.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
request.HTTPBody = trimmedPostParam.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
guard error == nil && data != nil else {
// check for fundamental networking error
print("error=\(error)")
return
}
if let httpStatus = response as? NSHTTPURLResponse where httpStatus.statusCode != 200 {
// check for http errors
print("statusCode should be 200, but is \(httpStatus.statusCode)")
print("response = \(response)")
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)
let result : AnyObject = responseString!.parseJSONString!
if let nsMutableResult = result as? NSMutableArray{
print("NSMutableArray")
}
if let nsDictResult = result as? NSMutableDictionary{
self.parseMutableDictionary(nsDictResult)
}
self.flag = true // true if download succeed,false otherwise
completed(success: flagAsyncCall!)
}
task.resume()
}
答案 0 :(得分:0)
在登录按钮上按下呼叫:
apiCall.callCheckIsUserLogged(nil, password : self.passwordField.text, email: self.mailField.text){ (ok) in
if ok {
self.performSegueWithIdentifier("Identifier", sender: self)
} else {
print("User not logged in")
}
}
因为如果用户登录了,您的callCheckIsUserLogged
方法已经返回。
internal typealias completion = (success : Bool) -> Void