7

I just started coding in Swift and I have the following code which parses JSON

func parse (latitude: Double, longtitude: Double){


    let jsonUrlString = "https://api.darksky.net/forecast/apiKey/\(latitude),\(longtitude)"

    guard let url = URL(string: jsonUrlString) else{
        return
    }

    var information: forecast?
    URLSession.shared.dataTask(with: url) { (data, res, err) in

        guard let data = data else { 
              return
        }

        do {
            let json = try JSONDecoder().decode(forecast.self, from: data)
            self.info = json

        } catch {
            print("didnt work")
        }

    }.resume()

    processJson(info)
}

My problem is that I want to pass data that is stored in JSON to a variable in the class to be processed using processJson function but since the dataTask function does not return any values, and JSON variable is locally stored I cannot process info variable outside the class (it always returns nil). I was wondering what is the solution to this problem? I'm facing the same problem with weather.getCoordinate().

5
  • Your Secret Key must be required for API calling in Darksky so, you read Document for add your Secret key: darksky.net/dev/docs example : api.darksky.net/forecast/[yoursecretkey]/37.8267,-122.4233 Commented Sep 14, 2017 at 5:14
  • Yea, I do have an API. I just removed so no one can use it here. Thanks though Commented Sep 14, 2017 at 5:16
  • You're using URLSession to make your request to the API, but URLSession make the call to the API asynchronously so the response of the request is handled using closures, this means that the line after the resume you're setting doesn't work at all because it will be called before the request finish and you variable is set. You should move it after set the variable in the closure Commented Sep 14, 2017 at 5:19
  • I tried that, but still can't access the data outside the function. here is what I did: do{ let json = try JSONDecoder().decode(forecast.self, from: data) print (json) self.info = json print("information",self.info?.currently) func process(uiLable:UILabel) { print("(self.info?.currently?.summary) •(self.info?.currently?.temperature)") } the first one prints the value, but when the second function is called it just prints nil! Commented Sep 14, 2017 at 5:38
  • here is a link to my project link Commented Sep 14, 2017 at 5:44

1 Answer 1

12

You can use completion block to return value. Add completion block your to function like this

func parse (latitude: Double, longtitude: Double, completion: @escaping ((AnyObject) -> Void)){
    let jsonUrlString = "https://api.darksky.net/forecast/apiKey/\(latitude),\(longtitude)"

    guard let url = URL(string: jsonUrlString) else{
        return
    }

    var information: forecast?
    URLSession.shared.dataTask(with: url) { (data, res, err) in

        guard let data = data else { 
              return
        }

        do {
            let json = try JSONDecoder().decode(forecast.self, from: data)
            self.info = json
            completion(info)
        } catch {
            print("didnt work")
        }

    }.resume()

And when you call this function, it return your info

parse( lat, long, {info in processJson(info) })

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.