我是Swift的新手,我对完成处理程序知之甚少。我想从API获取请求并解析JSON响应,以便我可以获取令牌。但是我的代码发生了什么,每当我调用<html>
<head>
<title>A Trello Dashboard</title>
<link rel="stylesheet" media="screen" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h1>Trello Dashboard</h1>
</div>
</body>
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="https://trello.com/1/client.js?key=mykey"></script>
<script type="text/javascript">
Trello.authorize({
type: 'popup',
name: 'A Trello Dashboard',
scope: {
read: 'true',
write: 'true'
},
expiration: 'never',
success: function() { console.log("Successful authentication"); },
error: function() { console.log("Failed authentication"); }
});
</script>
</html>
函数时,我的UI就会冻结并等待数据获取。以下是getAuthentication
getAuthentication
然后,我在我的LoginViewController中调用此方法。有人说我正在使用同步请求,这就是我的用户界面冻结的原因,但我真的不知道如何将其更改为异步并等待数据下载。有人可以帮我弄这个吗?任何帮助将不胜感激。
答案 0 :(得分:2)
首先,从您的函数中删除dispatch_semaphore
相关代码。
func getAuthentication(username: String, password: String){
let baseURL = "Some URL here"
let url = NSURL(string: baseURL)!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.HTTPBody = "{\n \"username\": \"\(username)\",\n \"password\": \"\(password)\"\n}".dataUsingEncoding(NSUTF8StringEncoding);
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
if error == nil{
let swiftyJSON = JSON(data: data!)
print(swiftyJSON)
//parse the data to get the user
self.id = swiftyJSON["id"].intValue
self.token = swiftyJSON["meta"]["token"].stringValue
} else {
print("There was an error")
}
}
task.resume()
}
在上面的代码中,函数dataTaskWithRequest
本身就是一个异步函数。因此,您不需要在后台线程中调用函数getAuthentication
。
添加完成处理程序
func getAuthentication(username: String, password: String, completion:((sucess: Bool) -> Void)){
let baseURL = "Some URL here"
let url = NSURL(string: baseURL)!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.HTTPBody = "{\n \"username\": \"\(username)\",\n \"password\": \"\(password)\"\n}".dataUsingEncoding(NSUTF8StringEncoding);
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
var successVal: Bool = true
if error == nil{
let swiftyJSON = JSON(data: data!)
print(swiftyJSON)
self.id = swiftyJSON["id"].intValue
self.token = swiftyJSON["meta"]["token"].stringValue
} else {
print("There was an error")
successVal = false
}
dispatch_async(dispatch_get_main_queue(), { () -> Void in
completion(successVal)
})
}
task.resume()
}
可以如下调用:
self.getAuthentication("user", password: "password", completion: {(success) -> Void in
})
答案 1 :(得分:1)
您可以将一个转义闭包参数传递给getAuthentication方法。
select * from Blog_CommentDetails
order by coalesce(ReplyCommentID, commentID), CommentID
在LoginViewController中调用getAuthentication,如下所示:
func getAuthentication(username: String, password: String, completion: (JSON) -> ()){
...
// create a request in the same way
...
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
if error == nil{
let swiftyJSON = JSON(data: data!)
print(swiftyJSON)
completion(swiftyJSON)
} else {
print("There was an error")
}
}
task.resume()
}
另一种方法是在LoginViewController中的后台线程中调用getAuthentication以避免阻塞主线程(即UI线程)。
getAuthentication(username, password) { (json) -> in
//Do whatever you want with the json result
dispatch_async(dispatch_get_main_queue()) {
// Do UI updates
}
}