0

I am a beginner Swift coder, and am attempting to parse JSON data from the NewsAPI website and use it. I have successfully parsed the JSON data and it is organized via my structs, but I am unable to set it to a variable outside of the background thread, use it outside of it. Any suggestions? I have included my code.

Thank you

import UIKit

class ViewController: UIViewController {

    var test:Int?

    override func viewDidLoad() {
        super.viewDidLoad()
        GrabJSON()


    }

    @IBOutlet weak var labelTime: UILabel!





    func GrabJSON() {

    // hit the API endpoint
         let urlString = "http://newsapi.org/v2/everything?q=bitcoin&from=2020-05-13&sortBy=publishedAt&apiKey=_________(it actually is here)"

         let url = URL(string: urlString)

         guard url != nil else {
             return

         }

         let session = URLSession.shared
         let dataTask = session.dataTask(with: url!) { (data, response, error) in

             // check for errors
             if error == nil && data != nil {
                 // if there is no error and there is data

                 let decoder = JSONDecoder()

                 do {


                 //parse json
             let newsFeed = try decoder.decode(NewsFeed.self, from: data!)

                    print(newsFeed)



             }
             catch {
                 print("error in JSON parsing")
             }

             }


         }

         // makes the API call

        dataTask.resume()

     }
}
Kon
  • 4,023
  • 4
  • 24
  • 38

1 Answers1

1

Since you session.dataTask() is asynchronous (you pass it a callback), you can similarly provide a callback parameter in your GrabJson function, like so:

func GrabJSON(callback: NewsFeed -> Void) {

     // hit the API endpoint
     let urlString = "http://newsapi.org/v2/everything?q=bitcoin&from=2020-05-13&sortBy=publishedAt&apiKey=_________(it actually is here)"

     let url = URL(string: urlString)

     guard url != nil else {
         return
     }

     let session = URLSession.shared
     let dataTask = session.dataTask(with: url!) { (data, response, error) in

         // check for errors
         if error == nil && data != nil {
             // if there is no error and there is data

             let decoder = JSONDecoder()

      do {

             //parse json
             let newsFeed = try decoder.decode(NewsFeed.self, from: data!)

                print(newsFeed)
                callback(newsFeed) // call the callback
         }
         catch {
             print("error in JSON parsing")
         }
     }

     // makes the API call
    dataTask.resume()
 }

Then elsewhere, you can use it like so:

GrabJson { newsFeed in 
   // do stuff with newsFeed json
}
Kon
  • 4,023
  • 4
  • 24
  • 38
  • Thank you for this, but I get an error when attempting to call the function now as anything I put in for callback gives me an error. Additionally, the GrabJSON newsFeed in doesn't work - any suggestions? I put it in as you suggested – pianocoder585 Jun 14 '20 at 02:24
  • @pianocoder585 without more details, I can't tell what the problem is. – Kon Jun 14 '20 at 14:42