Link to home
Start Free TrialLog in
Avatar of Hank Moody
Hank Moody

asked on

Cant access variables inside the DispatchQueue.main.async

The variable is empty outside the DispatchQueue.main.async and I dont know what to do exactly.
Im trying to make this work from so many days but I gave up now.

Please help...


func createData(request:Crudpb_CreateRequest) -> String {
    DispatchQueue.main.async {
        self.response = try! self.client.create(request)

        print("This is response 1: " + self.response.result) // <-------- This is priting the right response
    }
    print("This is response outside DispatchQueue: " + self.response.result) // <------- This is not printing anyvalue
    return self.response.result // <------ This is not
}

Open in new window

Avatar of Shahan Ayyub
Shahan Ayyub
Flag of Pakistan image

The reason it is not printing value as the process inside asyn block is an asynchronous process and it will not make the calling thread wait for it so when you read value you get nothing because the async process didn't complete yet, but in async block if you read value you get it since execution has been completed. You should refactor this function to pass value in a completion block instead of returning value from function.

Beside this you should make API call in a background thread and return result in main thread.

Something like this should work:
https://medium.com/@oleary.audio/simultaneous-asynchronous-calls-in-swift-9c1f5fd3ea32

A part from link:

func query(text: String, completion([Track]) -> Void) {
   let endpoint = "https://www.something.iforget/search"
   let url = URL(string: endpoint)
   var request = URLRequest(url: url)
   request.httpMethod = "GET"
   request.addValue(//whatever header fields are needed, I forget)
   let task = URLSession.shared.dataTask(with: request, completionHandler: {(data, response, error) in
      if let data = data {
         let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] ?? [:]
         //Here I parse the json into an array of Tracks
         completion([tracks])
      }
   })
   task.resume()
}

Open in new window


Based on above example your code should look like this:

func createData(request:Crudpb_CreateRequest, completion(TypeOfYourResponse) -> Void) {

   DispatchQueue.global(qos: .background).async { // call API in background thread
        self.response = try! self.client.create(request)

        DispatchQueue.main.sync { // return data in main thread
             completion(self.response)
             print("This is response 1: " + self.response.result) // <-------- This is priting the right response
       }
    }
}

Open in new window

This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.