2

I want to print fetched data from viewDidLoad. I don't want to print it from the custom function itself. when I call the fetch function in viewDidLoad.It should fetch all datas. and after that I should be able to access or print that data from viewDidLoad itself or wherever may be.

class ContactViewController: UIViewController {


@IBOutlet var lblEmail: UILabel!
@IBOutlet var lblLocation: UILabel!
@IBOutlet var mapUIView: UIView!

var email = String()
var location = String()
var lati = Double()
var long = Double()


override func viewDidLoad() {
    super.viewDidLoad()


    self.fetchData()
    print(email)
    self.lblEmail.text = self.email


}

func fetchData(){

    let manager = APIManager()
    manager.parsingGet(url: BaseURL.contact) { (JSON, Status) in

        if Status {
            let dict = JSON.dictionaryObject
            let data = dict!["data"] as! [String:Any]

           // let lat = data["latitude"] as! Double
           // let lon = data["longitude"] as! Double
            let mail = data["email"] as! String
            let loc = data["location"] as! String

            DispatchQueue.main.async {

                self.email = mail
                self.location = loc
               // self.lati = lat
               //self.long = lon

            }


        }


    }


}


}
Wings
  • 2,398
  • 23
  • 46
Jaseel.Dev
  • 730
  • 1
  • 7
  • 19
  • 2
    Related: [Returning data from async call in Swift function](https://stackoverflow.com/questions/25203556/returning-data-from-async-call-in-swift-function?r=SearchResults&s=1|67.5381) – rmaddy May 10 '19 at 06:49
  • 1
    Why do you insist on getting all the data before `viewDidLoad` returns? Getting data from the Internet takes _time_. – Sweeper May 10 '19 at 06:50

2 Answers2

3

You cannot print any data that you will be getting from an API response in viewDidLoad() method as all the lines of code specified in the viewDidLoad() method will be executed back to back and will not wait for your API call to be finished.

Even if you have a fast server it will take a couple of milliseconds to hit your API and get a response. Your compiler would have executed all lines of code with the viewDidLoad() method by then.

So you might as well print the data in DispatchQueue.main.async in your fetchData() method.

You can try using callback functions. That could be a possible way of achieving what you want. Try something like this ....

override func viewDidLoad() {
    super.viewDidLoad()


    getData(completion:{ result in
    print(email)
    self.lblEmail.text = self.email
})


}

func getData(completion: (Bool)->()) {
    if status{
        let dict = JSON.dictionaryObject
        let data = dict!["data"] as! [String:Any]
        let mail = data["email"] as! String
        let loc = data["location"] as! String

        DispatchQueue.main.async {

            self.email = mail
            self.location = loc
            completion(true)

        }

    } else {
        completion(false)
    }
}
Cedan Misquith
  • 1,134
  • 9
  • 20
2

parsingGet work asynchronously. The solution is pretty easy: Assign the value to the label in the completion handler of the API

override func viewDidLoad() {
    super.viewDidLoad()
    self.fetchData()
}

func fetchData() {

    let manager = APIManager()
    manager.parsingGet(url: BaseURL.contact) { (JSON, status) in

        if status {
            let dict = JSON.dictionaryObject
            let data = dict!["data"] as! [String:Any]

            // let lat = data["latitude"] as! Double
            // let lon = data["longitude"] as! Double
            let mail = data["email"] as! String
            let loc = data["location"] as! String

            self.email = mail
            self.location = loc
            print(mail)

            DispatchQueue.main.async {    
                self.lblEmail.text = mail
            }
        }
    }
}
vadian
  • 274,689
  • 30
  • 353
  • 361