如何围绕XML请求创建回调



我一直在努力了解回调在Swift中是如何工作的。我已经看了很多例子(比如这一个),这些例子帮助我更好地理解了回调,但我在正确实现回调方面运气不佳。

我有一个函数,它接受URL,从web api下载一些XML数据,然后将其解析为对象。同时,我有一个UILabel,它正在等待来自XML请求的一些数据。

下面是我想用回调设置的函数的部分示例。为了清楚起见,假设它只返回一个数据点,该数据点稍后将分配给UILabel

XMLUtility.swift

// global
var weekForecasts = [DayForecast]()
class XMLUtility {
func retrieveDataFromXML(myUrl: String) {
if let url = NSURL(string: myUrl) {
if let data = NSData(contentsOfURL: url) {
var error: NSError?
var cleanedData = filterData(data)
if let doc = AEXMLDocument(xmlData: cleanedData, error: &error) {
//... does some work parsing xml ////

for day in date {
//... some work assigning values /////
weekForecasts.append(thisDay)
}         
}   
}  
} 

问题出现在我的ViewController中。。。我有一些UILabels正在等待来自XML数据请求的值。加载ViewController时,XML尚未处理,标签无法接收值。

以下是我在ViewController中所做操作的简化示例:

ViewController.swift

@IBOutlet weak var currentTemperatureLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()

currentTemperatureLabel.text = // I get a value out of my [DayForecasts]
}

我理解为什么会出现这种情况,而且我对如何解决问题有着新手般的理解。我认为我需要使用回调,但根据我迄今为止看到的示例,我不确定如何实现回调。

我的问题:

给定提供的示例,我将如何将retrieveDataFromXML方法转换为回调。此外,我如何从ViewController调用函数来访问数据。

如有任何帮助,我们将不胜感激!

func retrieveDataFromXML(myUrl: String, completion: ((Array<DayForecast>) -> Void)) {
if let url = NSURL(string: myUrl) {
if let data = NSData(contentsOfURL: url) {
var error: NSError?
var cleanedData = filterData(data)
var weekForecasts = [DayForecast]() //local variable
if let doc = AEXMLDocument(xmlData: cleanedData, error: &error) {
//... does some work creating objects from xml
for day in date {
//... some work assigning values /////
weekForecasts.append(thisDay)
}    
//pass the local array into the completion block, which takes
//Array<DayForecast> as its parameter
completion(weekForecasts) 
}
}
}  
}

称为类似

//in this example it is called in viewDidLoad
func viewDidLoad() {
var urlString = "urlstring"
retrieveDataFromXML(urlString, {(result) -> Void in
//result is weekForecasts
//UI elements can only be updated on the main thread, so get the main 
//thread and update the UI element on that thread
dispatch_async(dispatch_get_main_queue(), {
self.currentTemperatureLabel.text = result[0] //or whatever index you want
return
})
})
}

这就是你的问题所要求的吗?

最新更新