0

Im having a problem with my swift code. I am trying to set the array yearsLinks to a value inside my closure and I am able to do this and print it while I am still in the closure but when i try to print the array values outside of the closure, it returns an empty array. why is this?.

Please help, I want to set the array values, yearsLinks to the cells in a tableview.

Here is a snippet of my code. Appreciate the help. Thank you so much :)

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

var url = String()
var yearsLinks = [String]()

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return yearsLinks.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell2", for: indexPath)
    cell.textLabel?.text = yearsLinks[indexPath.row]
    return cell
}

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    if let requests = URL(string: url){
        let request = NSURLRequest(url: requests)
        let task = URLSession.shared.dataTask(with: request as URLRequest){
            data, response, error in
            if error != nil {
                print(error as Any)
            } else {
                if let unwrappedData = data {
                    let wrappedData = NSString(data: unwrappedData, encoding: String.Encoding.utf8.rawValue)

                              ...
              //  THESE ARE JUST CODE TO GRAB THE ARRAY THAT I WANT
              //  linkyears IS AN ARRAY OF VALUES DECLARED IN THE CLOSURE THAT I WANT TO SET TO THE yearsLinks VARIABLE DECLARED OUTSIDE.          
                        self.yearsLinks = linkyears
                              ...

                        print(self.yearsLinks) // THIS WORKS FINE AND RETURNS AN ARRAY OF VALUES THAT I WANTED.
                    }
                }
            }

        }
        // TRYING TO ACCESS THE ARRAY OF VALUES IN THE yearsLinks ARRAY RETURNS AN EMPTY STRING??

        task.resume()

    }
}

}

Danesh
  • 61
  • 1
  • 7
  • "outside of the closure, it returns an empty array. why is this?" Because the concept you are missing is **Asynchrone**. For instance, add prints with "id", like `print("InsideClosure: \(self.yearLinks)")`, `print("AfterClosure: \(self.yearLinks)")`, look which one is print before/after, it's not the one you think. In the closure, once you did `self.yearLinks = ...`, just do `tableView.reloadData()` (and do in in main thread). – Larme Jul 25 '18 at 08:12
  • @Larme Thank you for your help but I tried to use DispatchQueue.main.async but it didn't work. Can you guide me as to how my code should be if I want to be able to link the values in yearLinks array to be presented in the table view cell method?? – Danesh Jul 25 '18 at 15:40

2 Answers2

0

The reason why it returns empty is that the print function is called even before the URL session. Not only that, the urlSession takes a while to get to the callback.

If you need to use the array, you can put a function that takes the array as an argument in the closure.

James Kim
  • 51
  • 4
  • Hi James thank you for your reply and I understand that the closure runs at the same time as the code outside of it and so it would not have had any values yet when I try to print it outside of the closure. But how do I get the values in the yearLinks array outside of the closure as I need them to be displayed in the Tableview cell method?? How exactly do I create a function that takes the array as an argument in the closure??? THANK YOU SO MUCH FOR YOUR HELP :) – Danesh Jul 25 '18 at 15:41
0

How did you print array values outside of the closure? This closure is asynchronous. If you want to print array , you can reload tableView then print it in UITableViewDelegate.

anjingpan
  • 31
  • 4