我想使用API请求获取数据。使用SwiftyJson和Alamofire获取数据。问题是获取数据但是在获取值之前加载了视图。我如何解决问题?我的代码如下:
func fetchData(){
Alamofire.request(favUrl, method: .get, parameters: [:]).responseJSON {
response in
if response.result.isSuccess{
let dataFetched : JSON = JSON(response.result.value!)
//print(dataFetched)
let titleDisp = dataFetched["title"].arrayObject as? [String]
//print(titleDisp)
self.trackList = dataFetched["track_id"].arrayObject as? [String]
print(self.trackList)
}else{
print("Error \(String(describing: response.result.error))")
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
fetchData()
}
答案 0 :(得分:0)
Alamofire mathod以异步方式运行。不在UIThread中。然后在完成方法运行后必须重新加载这些视图。
例如 - tableview
func fetchData(){
Alamofire.request(favUrl, method: .get, parameters: [:]).responseJSON {
response in
if response.result.isSuccess{
let dataFetched : JSON = JSON(response.result.value!)
//print(dataFetched)
let titleDisp = dataFetched["title"].arrayObject as? [String]
//print(titleDisp)
self.trackList = dataFetched["track_id"].arrayObject as? [String]
print(self.trackList)
// In here you have to reload, set your uiviews or all calculation
tableview.reloadData()
}else{
print("Error \(String(describing: response.result.error))")
}
}
}
答案 1 :(得分:0)
了解应用程序运行多个线程非常重要。主线程(也称为UI线程)执行应用程序可见部分的操作,包括显示视图,对按钮作出反应等。
您无法阻止主线程。
当你调用外部资源(如API调用或加载外部图像)时,它们会在一个单独的线程上执行。该线程独立于主线程。两个线程都没有等待另一个。在加载数据时,应用程序仍会对按钮作出反应。您要求的是在加载数据之前阻止显示视图。您可以这样做,但您必须了解这可能需要一些时间,具体取决于您的网络连接。您可以采取两种方法。
转换到显示数据但放置" Loading"屏幕上的元素,直到数据加载,然后删除"加载"元素然后用数据重新显示视图。
在显示视图之前加载数据。使前一个视图加载数据,然后转到必须显示数据的视图。
您还必须确定此数据是加载ONCE还是每次显示视图时。通过将调用放在viewDidLoad中,API调用只会发生一次,直到重新启动应用程序。如果您希望每次显示屏幕时都加载数据,请将调用放在viewWillAppear。
中// Approach #1
func fetchData(){
self.showSpinner()
Alamofire.request(favUrl, method: .get, parameters: [:]).responseJSON {
response in
self.hideSpinner()
if response.result.isSuccess {
let dataFetched : JSON = JSON(response.result.value!)
//print(dataFetched)
let titleDisp = dataFetched["title"].arrayObject as? [String]
//print(titleDisp)
self.trackList = dataFetched["track_id"].arrayObject as? [String]
print(self.trackList)
// Actually update the relevant screen elements here.
} else {
print("Error \(String(describing: response.result.error))")
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
//fetchData()
}
override func viewWillAppear() {
super.viewWillAppear()
fetchData()
}
func showSpinner() {
// IMPLEMENT ME
}
func hideSpinner() {
// IMPLEMENT ME
}