0

I am relatively new to Swift so please excuse any rookie errors. I am retrieving some data from a web service and serialising the data into an object. However, when I return this object from the enclosing function, it is always null. If I run this code all in the ViewController however, it works fine. It only seems to fail when I split my code out into separate classes/methods (I am trying to implement better practises). I should also add that no error is printed from the print(error) statement.

Thanks in advance for any help!

    func getLocationData(lat: String, long: String) -> Location {
    locationUrl += lat + "&lon=" + long
    print("Location query: " + locationUrl)

    let request = NSMutableURLRequest(url: NSURL(string: locationUrl)! as URL)
    request.httpMethod = "GET"
    var location: Location?

    _ = URLSession.shared.dataTask(with: request as URLRequest, completionHandler:
        {(data, response, error) -> Void in
            if (error != nil) {
                print("Error making requets to web service")
            } else {
                do {
                    location = try JSONDecoder().decode(Location.self, from: data!)
                } catch let error as NSError {
                    print(error)
                }
            }
    }).resume()

    return location!
}

enter image description here enter image description here

Jakmoore
  • 59
  • 8

1 Answers1

1

Your code is asynchronous so location var is nil when you force-unwrap it as the response isn't yet returned , you need a completion

func getLocationData(lat: String, long: String,completion:@escaping (Location?) -> ()) {
    locationUrl += lat + "&lon=" + long
    print("Location query: " + locationUrl)

    var request = URLRequest(url: URL(string: locationUrl)!)
    request.httpMethod = "GET" 
    _ = URLSession.shared.dataTask(with: request as URLRequest, completionHandler:
        {(data, response, error) -> Void in
            if (error != nil) {
                print("Error making requets to web service")
            } else {
                do {
                    let location = try JSONDecoder().decode(Location.self, from: data!)
                    completion(location)
                } catch {
                    print(error)
                    completion(nil)
                }
            }
    }).resume()

}

Call

getLocationData(lat:////,long:////) { loc in 
  print(loc)
}
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87
  • Thank you for your response. I have updated my question to show a picture of the errors shown when I modify my code to incorporate your suggestion. – Jakmoore Jun 05 '19 at 18:46
  • 1
    @Jakmoore It's just a typo. In the first line replace `Location>` with `Location?` – vadian Jun 05 '19 at 18:50