2

I am trying to get a function that calls an API via HTTP request and return a String. My request function has a completion handler that returns the Data and it is used by my function.

func buildHTML () -> String {
    var htmlString: String = ""

    request(url: "https://someurl.com/api/getalldata") { (jsonData: Data) in
        let units = try JSONDecoder().decode([MyUnits].self, from: jsonData)
            for unit in units {
                //Building my html string here
                htmlString += "......."
            }
    }
    return htmlString
}

However this does not work, because the htmlString returned as an empty string, How can I get this string out to return it by buildHTML?

Any idea is welcomed!

shallowThought
  • 19,212
  • 9
  • 65
  • 112
Oswaldo Rubio
  • 50
  • 2
  • 9

2 Answers2

4

Since your request is asynchronous you will not be able to return a result as your return statement will execute before your closure is executed. The solution, in this case, is to use a completion handler in your outer function as well:

func buildHTML(_ completion: @escaping (String)->Void) {
    var htmlString: String = ""

    request(url: "https://someurl.com/api/getalldata") { (jsonData: Data) in
        let units = try JSONDecoder().decode([MyUnits].self, from: jsonData)
            for unit in units {
                //Building my html string here
                htmlString += "......."
            }
        completion(htmlString)
    }
}
creeperspeak
  • 5,403
  • 1
  • 17
  • 38
0

My solution will block the current thread, but it is synchronous. You can use Data.

func buildHTML(_ completion: @escaping (String)->Void) {
    var htmlString: String = ""
    let url = URL(string: "https://someurl.com/api/getalldata")!

    guard let jsonData = try? Data(contentsOf: url) else {
        print("There was an error!")
        // return or break
    }

    let units = try JSONDecoder().decode([MyUnits].self, from: jsonData)
    for unit in units {
        //Building my html string here
        htmlString += "......."
    }
    completion(htmlString)
}
Kryštof Matěj
  • 462
  • 3
  • 16