79716

How would I create a callback around an XML request?

Question:

I've been trying to understand how callbacks work in Swift. I've gone over quite a few examples (<a href="https://stackoverflow.com/questions/27208198/function-does-not-wait-until-the-data-is-downloaded" rel="nofollow">like this one</a>) that have helped me to better understand callbacks, but I haven't had any luck in properly implementing one.

I have a function that accepts a URL, downloads some XML data from a web api and then parses it into objects. At the same time I have a UILabel that is waiting for some data from the XML request.

Below is a partial example of my function that I'd like to set up with a callback. For the sake of clarity just assume it only returns a single data point which which will be assigned to a <strong>UILabel</strong> later:

<strong>XMLUtility.swift</strong>

// 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) } } } }

The problem occurs in my ViewController... I have some UILabels that are waiting for values from the XML data request. When the ViewController loads, the XML hasn't processed yet and the label failed to receive a value.

Here's a simplified example of what I am doing in my ViewController:

<strong>ViewController.swift</strong>

@IBOutlet weak var currentTemperatureLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() currentTemperatureLabel.text = // I get a value out of my [DayForecasts] }

I understand why this is the case, and I have a novice understanding of how to solve the problem. I believe I need to use a callback but, based on the examples I have seen so far, I am not sure how to implement one.

<h2>My question:</h2>

Given the example provided, how would I convert my retrieveDataFromXML method into a callback. Additionally, how do I call the function from my ViewController to access the data.

Any help on this would be greatly appreciated!

Answer1:

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) } } } }

called like

//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 }) }) }

Is this what your question was asking for?

Recommend

  • Deleting in NSDocumentDirectory
  • How create UIImage from bytes?
  • Determine if Finder can be safely killed
  • Scope in JavaScript / jQuery [duplicate]
  • Filling web form via PowerShell does not recognize the values entered
  • How to implement AVAudioPlayer Inside Singleton Method?
  • Swift 3 Migration - Double Extension rounding issue
  • Error Domain=NSCocoaErrorDomain Code=3840 “Invalid value around character 0.” UserInfo={NSDebugDescr
  • How to embed private Objective-C framework into iOS app on Xcode 6 with workspaces
  • Is Bolts framework[Parse+Facebook] need to use parse webservice?
  • Error combining NSCalendarUnit with OR (pipe) in Swift 2.0
  • Google App Indexing not resolving for Swift?
  • simple way to map a json collection response into swift object class
  • Getting the parameterised type of a generic in swift?
  • Smart URL with optional parameters?
  • How to use the File System Events API in Swift?
  • Remove every nth element from swift array
  • How to access UIViewController's varaibles inside “func applicationWillResignActive”? Swift, iO
  • Get the negative of an Optional Chain
  • No such module 'Parse' following Parse iOS Swift Quickstart guide
  • Custom Nav Title offset ios 11
  • Want to understand iframe breakout code
  • How can we prepend rows to a react native list-view?
  • Connect .sks to skscene.h
  • Functions in global context
  • Update CALayer sublayers immediately
  • Counter field in MS Access, how to generate?
  • swift auto completion not working in Xcode6-Beta
  • Possible to stop flickering java tooltip in heavyweight mode?
  • sending/ receiving email in Java
  • How to set my toolbar fixed while scrolling android
  • AT Commands to Send SMS not working in Windows 8.1
  • Circular dependency while pushing http interceptor
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • AngularJs get employee from factory
  • How to set the response of a form post action to a iframe source?
  • Change div Background jquery
  • apache spark aggregate function using min value
  • XCode 8, some methods disappeared ? ex: layoutAttributesClass() -> AnyClass
  • Sorting a 2D array using the second column C++