1

I am using this function to call json information from a database - it gets the information fine.

But it does not continue after the "getHistoricalMonthlyData". so it will not get to the print("****** line 55"). (yes, I plan on making this a func once I figure out the issue.)

it will print the "print(i.stock)" fine.

I can share the "getHistoricalMonthlyData" code but it works fine and I doubt that is the issue.

I am not great with the completion handlers and I suspect that is the issue?

below is the "getHistoricalMonthlyData" function that I can not get past.

func calculateMonthPerformance (setting: settings) {

    let set = setting
    let u = User.getUser()
    var i = Indexes()


      getHistoricalMonthlyData(symbol: symbol, beg: set.monthBeg, end: set.monthEnd) { (json, error ) in

            if let error = error {
                print ("error", error)

            } else if let  json = json {
                print ("success")
                i.stock = json
                print(47)
            }

          // this is fine
          print(50)
          print(i.stock)

        }

     // nothing at this point
     print("****** line 55")

 }

This is how the json function is set up and works great in another project.

it has a resume.

 func getHistoricalMonthlyData(symbol: String, beg: Date, end: Date, completionHandler: @escaping ([HistoricalData]?, Error?) -> Void) {

let beg = beg.dateAtStartOf(.month).toFormat("yyyy-MM-dd")
let end = end.dateAtEndOf(.month).toFormat("yyyy-MM-dd")

let jsonUrl = "https://eodhistoricaldata.com/api/eod/\(symbol).US?from=\(beg)&to=\(end)&api_token=\(EOD_KEY)&period=eom&fmt=json"


guard let url = URL(string: jsonUrl) else {
    print("Error: cannot create URL")
    let error = BackendError.urlError(reason: "Could not create URL")
    completionHandler(nil, error)
    return
}

URLSession.shared.dataTask(with: url) { (data, response, error) in

    guard error == nil else {
        completionHandler(nil, error!)
        return
    }

    guard let jasonData = data else {
        print("Error: did not receive data")
        let error = BackendError.objectSerialization(reason: "No data in response")
        completionHandler(nil, error)
        return
    }

    do {

        let historical = try JSONDecoder().decode([HistoricalData].self, from: jasonData )

        completionHandler(historical, nil)

    } catch let jsonErr {
        print ("Error serializing json", jsonErr )
        let error = BackendError.objectSerialization(reason: "Couldn't create a todo object from the JSON")
        completionHandler(nil, error)

    }

}.resume()

}

thanks.

diogenes
  • 1,865
  • 3
  • 24
  • 51
  • Does your getHistoricalMonthlyData has a `resume()` call for the URLSession dataTask? See for instance [this question](https://stackoverflow.com/questions/42705278/swift-url-session-and-url-request-not-working) – Joakim Danielson Oct 12 '19 at 07:57
  • yes. } catch let jsonErr { print ("Error serializing json", jsonErr ) let error = BackendError.objectSerialization(reason: "Couldn't create a todo object from the JSON") completionHandler(nil, error) } }.resume() } – diogenes Oct 12 '19 at 08:54
  • wow, this is way above my pay grade. (ok, I do this for fun and not get paid.) – diogenes Oct 12 '19 at 08:57

1 Answers1

0

if someone knows a better answer would love to hear about it.

I added a DispatchSemaphore to the code and it seems to work.

cheers.

let semaphore = DispatchSemaphore(value: 0)

URLSession.shared.dataTask(with: url) { (data, response, error) in

    guard error == nil else {
        completionHandler(nil, error!)
        return
    }

    guard let jasonData = data else {
        let error = BackendError.objectSerialization(reason: "No data in response")
        completionHandler(nil, error)
        return
    }

    do {

        let historical = try JSONDecoder().decode([HistoricalData].self, from: jasonData )

        completionHandler(historical, nil)

    } catch let jsonErr {
        let error = BackendError.objectSerialization(reason: "Couldn't create a todo object from the JSON")
        completionHandler(nil, error)

    }

    semaphore.signal()

}.resume()

_ = semaphore.wait(timeout: .distantFuture)
diogenes
  • 1,865
  • 3
  • 24
  • 51