当您使用内容填充字段时,我有字段和按钮,然后单击按钮:
@IBAction func dpSomething(_ sender: UIButton) {
activityIndicator.startAnimating()
activityIndicator.isHidden = false
field.isHidden = true
send.isHidden = true
let url = "http://urlwithjson"
let session = URLSession.shared
DispatchQueue.main.async { [unowned self] in
let task = session.dataTask(with: URL(string: url)!) { (data, response, error) in
if(error==nil){
do {
let jsonData = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary
if((jsonData["response"] as! Int) == 0){
self.responseL.text = "no results"
}
self.activityIndicator.stopAnimating()
self.responseL.isHidden = false
} catch _ {}
}
}
task.resume()
}
}
当我使用打印时,它几乎立即打印出JSON,但活动指示器需要10-20秒消失或有时它不会消失。有人可以告诉我为什么吗?而且当我更改标签中的文本时,我在控制台中收到错误:
此应用程序正在从后台线程修改autolayout引擎,这可能导致引擎损坏和奇怪的崩溃。这将在将来的版本中引发异常。
为什么会这样?
答案 0 :(得分:4)
首先在activityIndicator.startAnimating()
之后添加以下代码,此代码将隐藏您调用self.activityIndicator.stopAnimating()
的活动指示符:
activityIndicator.hidesWhenStopped = true
如果响应成功,您只是隐藏活动指示器,因此当catch块中出现错误时您可能需要隐藏指示符,当您从api响应中收到错误时,可能需要隐藏指示符
另一点是,当你提出请求时,它不应该在主线程中,只在后台,然后当你需要更新UI然后使用主线程时,所以最后这里是你可能需要的完整代码: / p>
@IBAction func dpSomething(_ sender: UIButton) {
activityIndicator.startAnimating()
activityIndicator.isHidden = false
activityIndicator.hidesWhenStopped = true
field.isHidden = true
send.isHidden = true
let url = "http://urlwithjson"
let session = URLSession.shared
let task = session.dataTask(with: URL(string: url)!) { (data, response, error) in
if(error==nil){
do {
let jsonData = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary
if((jsonData["response"] as! Int) == 0){
DispatchQueue.main.async {
//Update your UI here
self.responseL.text = "no results"
}
}
DispatchQueue.main.async {
//Update your UI here
self.activityIndicator.stopAnimating()
self.responseL.isHidden = false
}
} catch _ {
// JSONSerialization error might happen so hide the indicator
DispatchQueue.main.async {
//Update your UI here
self.activityIndicator.stopAnimating()
self.responseL.isHidden = false
}
}
}else {
// api response error might happen so hide the indicator
DispatchQueue.main.async {
//Update your UI here
self.activityIndicator.stopAnimating()
self.responseL.isHidden = false
}
}
}
task.resume()
}
答案 1 :(得分:2)
您只需对UI
线程进行main
更改,就不要在主线程上调用异步API调用。
let task = session.dataTask(with: URL(string: url)!) { (data, response, error) in
if(error==nil){
do {
let jsonData = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary
if((jsonData["response"] as! Int) == 0){
self.responseL.text = "no results"
}
DispatchQueue.main.async {
self.activityIndicator.stopAnimating()
self.activityIndicator.isHidden = true
self.responseL.isHidden = false
}
} catch _ {}
}
}
task.resume()