I'm trying to learn SwiftUI by converting a shell script to a SwiftUI app. It involves parsing some XML data that comes from the web. I managed to get the parsing to work using sample data, but when I tried to add the final piece, actually grabbing the data from the web, I got stuck. I found some sample code that works by itself, but when I tried to put it into a function that would take a URL and return the data, it returns an empty string. I guess it's an async problem, but I can't find sample code that will work for me. This is an app that only I will use. Here is what I have.
func doHttpCall(st : String) -> String {
var xmlData = ""
let url = URL(string: st)!
let task = URLSession.shared.dataTask(with: url) {(data, response, error) in
guard let data = data else { return }
xmlData = String(data: data, encoding: .utf8)!
print(xmlData)
}
task.resume()
return xmlData
}
It does fetch the data, as it is printing it, but it's returning an empty string. Any help will be appreciated.
That’s because doHTTPCall(…)
is a synchronous function but networking is inherently asynchronous. You’re calling dataTask(…)
, which is an asynchronous callback-based routine. It starts the network request and then returns, and later on it calls the closure with the results. In most cases doHTTPCall(…)
has already returned by the time that happens.
There are two ways you can tackle this:
-
Rework
doHTTPCall(…)
to use the same approach asdataTask(…)
, that is, take a completion handler that it calls when it’s done. -
Change
doHTTPCall(…)
to a Swift async function. That’ll allow it to call thedata(for:delegate:)
method, which is also an async function.
Given that you’re just starting out, I recommend that use the second approach.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"