UIView 在使用 SwiftyJSON 和 Alamofire 从 API 返回的数据之前被渲染
Posted
技术标签:
【中文标题】UIView 在使用 SwiftyJSON 和 Alamofire 从 API 返回的数据之前被渲染【英文标题】:UIView got rendered before data from API returned using SwiftyJSON and Alamofire 【发布时间】:2017-11-24 03:24:34 【问题描述】:我想使用 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()
【问题讨论】:
你是说视图在数据加载之前就出现了?如果这是您要问的,从您的描述中不完全清楚吗?你提到你将在你的应用程序的各个部分使用这些数据。这是问题的一部分吗?编辑您的问题并加强对问题的描述。 视图在加载数据之前出现。我希望先加载获取的数据。 你打算在什么样的地方展示这些数据。如tableview、imageview 获取的数据是一个数组。我将在 textViews 中使用它,甚至在计算视图的高度等等。 所有计算的事情都需要在这个方法结束时完成,如下所述 【参考方案1】:了解应用程序运行多个线程很重要。主线程,也称为 UI 线程,执行应用程序可见部分的操作,包括显示视图、对按钮做出反应等。
您不能阻塞主线程。
当您调用外部资源(如 API 调用或加载外部图像)时,这些资源会在单独的线程上执行。该线程独立于主线程。两个线程都不等待另一个。加载数据时,应用程序仍会对按钮做出反应。您要求的是在加载数据之前阻止显示视图。您可以这样做,但您必须了解这可能需要一些时间,具体取决于您的网络连接。您可以采用两种方法。
转换到显示数据的视图,但在屏幕上放置一个“正在加载”元素,直到数据加载,然后移除“正在加载”元素,然后重新显示包含数据的视图。
在显示视图之前加载数据。让前一个视图加载数据,然后转到必须显示数据的视图。
您还必须决定该数据是加载一次还是每次显示视图时加载。通过将调用放在 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
【讨论】:
【参考方案2】:Alamofire 方法异步运行。不在 UIThread 中。然后您必须在方法运行完成后重新加载这些视图。
作为示例 - 表格视图
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))")
【讨论】:
以上是关于UIView 在使用 SwiftyJSON 和 Alamofire 从 API 返回的数据之前被渲染的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 Alamofire 和 SwiftyJSON 在 tableviewcell 中加载 JSON 数据
在 Haneke 和 SwiftyJSON 之间转换 JSON
iOS:使用 HanekeSwift 和 SwiftyJSON