Web 请求会话中的完成处理
Completionhandling in webrequest session
我有一个带有 jsonserialization 的网络请求,之后是一个 for-in 获取过程。
整个过程大约需要 5-7 秒。
之后我想在 Viewcontroller 中引用我的表格视图。
该函数的方案如下所示。
public struct Container {
let name: String
let symbol: String
let rank: String
}
public var dataArray = [Container]()
func fetchNewData() {
var view = ViewController()
// WebbRquest...
// Json serialization...
// the following list is much longer, will take a while...
for items in json {
let name = items["name"] as? AnyObject;
let symbol = items["symbol"] as? AnyObject;
let rank = items["rank"] as? AnyObject;
let result = Container(name: name! as! String, symbol: symbol! as! String,rank: rank! as! String)
dataArray.append(result)
}
// Now, after alle the work is done, i want to reload the tableview in Viewcontrller:
view.reload()
// Here i´m getting error, because nothing will be executed after return.
}
webrequest进程结束后,如何调用reload函数?因为在 return 之后,该函数不再执行任何操作。
当 fetchNewData() 函数完成时,没有其他函数会 "know"。
感谢您的帮助!
@IBAction func updateButton(_ sender: Any) {
fetchNewData()
}
根据Phillipps的建议,我不得不稍微修改@IBAction func。
但现在它正在工作。惊人的!
这里是完整的工作版本:
public struct Container {
let name: String
let symbol: String
let rank: String
}
public var dataArray = [Container]()
func fetchNewData(completion:@escaping ([Container])->()) {
var view = ViewController()
// WebbRquest...
// Json serialization...
// the following list is much longer, will take a while...
for items in json {
let name = items["name"] as? AnyObject;
let symbol = items["symbol"] as? AnyObject;
let rank = items["rank"] as? AnyObject;
let result = Container(name: name! as! String, symbol: symbol! as! String,rank: rank! as! String)
dataArray.append(result)
}
completion(dataArray)
}
这是 actionFunc:
@IBAction func upDateButton(_ sender: Any) {
let data = dataArray
fetchNewData() {_ in (data)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
这是一个开始。这将是模糊的,因为我正在猜测我看不到的代码,但你可以将它转换为你自己的需要。
更改获取函数,使其将闭包作为参数:
func fetchNewData(completion:([Container])->()) {
...请注意,闭包在调用时将接受数据数组。
在你的 json 全部被解析之后,你可以调用闭包:
dataArray.append(result)
}
completion(dataArray)
"magic" 在视图控制器中,您可以在视图控制器中告诉 fetchNewData
完成后要做什么。类似于:
@IBAction func updateButton(_ sender: Any) {
fetchNewData() {(data)
// Save the data where the view controller can use it
self.tableArray = data
// Main queue for UI update
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
注意闭包是写在view controller里面的,所以self
是view controller。这意味着无需在 fetch 中创建第二个(无用的)控制器。
我有一个带有 jsonserialization 的网络请求,之后是一个 for-in 获取过程。 整个过程大约需要 5-7 秒。 之后我想在 Viewcontroller 中引用我的表格视图。 该函数的方案如下所示。
public struct Container {
let name: String
let symbol: String
let rank: String
}
public var dataArray = [Container]()
func fetchNewData() {
var view = ViewController()
// WebbRquest...
// Json serialization...
// the following list is much longer, will take a while...
for items in json {
let name = items["name"] as? AnyObject;
let symbol = items["symbol"] as? AnyObject;
let rank = items["rank"] as? AnyObject;
let result = Container(name: name! as! String, symbol: symbol! as! String,rank: rank! as! String)
dataArray.append(result)
}
// Now, after alle the work is done, i want to reload the tableview in Viewcontrller:
view.reload()
// Here i´m getting error, because nothing will be executed after return.
}
webrequest进程结束后,如何调用reload函数?因为在 return 之后,该函数不再执行任何操作。 当 fetchNewData() 函数完成时,没有其他函数会 "know"。 感谢您的帮助!
@IBAction func updateButton(_ sender: Any) {
fetchNewData()
}
根据Phillipps的建议,我不得不稍微修改@IBAction func。 但现在它正在工作。惊人的! 这里是完整的工作版本:
public struct Container {
let name: String
let symbol: String
let rank: String
}
public var dataArray = [Container]()
func fetchNewData(completion:@escaping ([Container])->()) {
var view = ViewController()
// WebbRquest...
// Json serialization...
// the following list is much longer, will take a while...
for items in json {
let name = items["name"] as? AnyObject;
let symbol = items["symbol"] as? AnyObject;
let rank = items["rank"] as? AnyObject;
let result = Container(name: name! as! String, symbol: symbol! as! String,rank: rank! as! String)
dataArray.append(result)
}
completion(dataArray)
}
这是 actionFunc:
@IBAction func upDateButton(_ sender: Any) {
let data = dataArray
fetchNewData() {_ in (data)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
这是一个开始。这将是模糊的,因为我正在猜测我看不到的代码,但你可以将它转换为你自己的需要。
更改获取函数,使其将闭包作为参数:
func fetchNewData(completion:([Container])->()) {
...请注意,闭包在调用时将接受数据数组。 在你的 json 全部被解析之后,你可以调用闭包:
dataArray.append(result)
}
completion(dataArray)
"magic" 在视图控制器中,您可以在视图控制器中告诉 fetchNewData
完成后要做什么。类似于:
@IBAction func updateButton(_ sender: Any) {
fetchNewData() {(data)
// Save the data where the view controller can use it
self.tableArray = data
// Main queue for UI update
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
注意闭包是写在view controller里面的,所以self
是view controller。这意味着无需在 fetch 中创建第二个(无用的)控制器。