Calling a POST Form with URLSession.shared.dataTask

People,

I am a very BEGINNER in swiftui programming, so my excuses for any fool question.

I have a POST (URLSession) that is updating my variables only in the second run (I will explain)

I put a print to see where code is passing and in immediate panel shows like this:

Passed 01 ===========
Passed 03 ===========
Passed 04 =========== out off func!!
2021-05-04 11:41:16.460925-0300 Fuel[2348:100030] [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed
Passou 02 ===========
Status: true
Nome: Roberto Pires 

(I didn't understand libquic failed, but the problem is another one)

Well, the correct should be:

Passed 01 ===========
Passou 02 ===========. <- SHOULD PASS HERE FIRST
Status: true
Nome: Roberto Pires 
Passed 03 ===========
Passed 04 =========== out off func!!
2021-05-04 11:41:16.460925-0300 Fuel[2348:100030] [] nw_protocol_get_quic_image_blockinvoke dlopen libquic failed



My code is called by a button, but returns BEFORE complete (and as so, show an incorrect Alert, because the
"myJsonResponse?.status"_ is false at this time), but the code is still running inside de func (surprisingly) and complete all the POST information correctly.

Why is not entering inside URLSession.shared.dataTask lines in the first time ?

Here is my code:

Code Block
  func validatingLogin()  {
      guard let myUrl = URL(string: "http://www.rcpires.com/apps/main.asp") else {
         print("URL invalid")
         return
      }
      var request = URLRequest(url: myUrl)
      request.httpMethod = "POST"
      let postString = usuario.loginPost()
      request.httpBody = postString.data(using: String.Encoding.utf8)
      print(“Passed 01 ===========")
      URLSession.shared.dataTask(with: request) { data, response, error in
        print("Passed 02 ===========")
         guard let myJson = data else {
            print(“Data not found")
            return
         }
         if let decodedData = try? JSONDecoder().decode(MyJSONResponse.self, from: myJson) {
            DispatchQueue.main.async {
               self.myJsonResponse = decodedData
               print("Status: \(myJsonResponse?.status ?? false)")
               print("Nome: \(myJsonResponse?.nome ?? "")")
              return
            }
         } else {
            let dataString = String(decoding: myJson, as: UTF8.self)
            print (“Invalid answer: \(dataString.description)")
            return
         }
      }.resume()
      print("Passed 03 ===========")
   }



This is called by my Login Button:
Code Block
 Button(action: {
    validatingLogin()
    if aspStatus.success == false {
       print("Passed 04 ========== out off func!”)
       isAlert = true
    } else {
       isLogin = true
    }
  }, label: {
      HStack {
        Image("checkmark").frame(width: 25, height: 15, alignment: .leading)
        Text("Entrar").bold()
     }
}) 


Thanks in advance to every good soul that helps me.
Answered by OOPer in 673268022

I put a print to see where code is passing and in immediate panel shows like this:

Passed 01 ===========
Passed 03 ===========
Passed 04 =========== out off func!!
2021-05-04 11:41:16.460925-0300 Fuel[2348:100030] [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed
Passou 02 ===========
Status: true
Nome: Roberto Pires 

(I didn't understand libquic failed, but the problem is another one)

Seems your code is working correctly.

Well, the correct should be:

NO, it is not correct.

My code is called by a button, but returns BEFORE complete (and as so, show an incorrect Alert, because the "myJsonResponse?.status"_ is false at this time), 

It is the right behavior, when you want to work with async methods. An async method itself returns to caller BEFORE complete, and the completion handler is executed after the task is completed.

This is called by my Login Button:

What is aspStatus? It does not appear in validatingLogin().


In the near future, you may need to learn async/await pattern in Swift, but you need to be accustomed with completion handler pattern until then.

You need to write everything you want to run after the task is completed within the completion handler.
Accepted Answer

I put a print to see where code is passing and in immediate panel shows like this:

Passed 01 ===========
Passed 03 ===========
Passed 04 =========== out off func!!
2021-05-04 11:41:16.460925-0300 Fuel[2348:100030] [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed
Passou 02 ===========
Status: true
Nome: Roberto Pires 

(I didn't understand libquic failed, but the problem is another one)

Seems your code is working correctly.

Well, the correct should be:

NO, it is not correct.

My code is called by a button, but returns BEFORE complete (and as so, show an incorrect Alert, because the "myJsonResponse?.status"_ is false at this time), 

It is the right behavior, when you want to work with async methods. An async method itself returns to caller BEFORE complete, and the completion handler is executed after the task is completed.

This is called by my Login Button:

What is aspStatus? It does not appear in validatingLogin().


In the near future, you may need to learn async/await pattern in Swift, but you need to be accustomed with completion handler pattern until then.

You need to write everything you want to run after the task is completed within the completion handler.
Thanks OOPer, I understand what you wrote, so, to my needs, I shoud make exactly the same thing but synchronous.
I will look for it, if you have some basic writing about it, let me know

aspStatus is a Class that return to me true or false (if false, a message why its false):

Code Block
class AspStatus {
   var success: Bool
   var message: String
   
   init(success: Bool, message: String) {
      self.success = success
      self.message = message
   }
}


I just don't understand your last part:

You need to write everything you want to run after the task is completed within the completion handler.


aspStatus is a Class that return to me true or false (if false, a message why its false):

Thanks for showing the class. But you have not shown the declaration of aspStatus (I do not mean AspStatus), nor any code using the class AspStatus. So it does not give any useful info to me.

I just don't understand your last part:

In your case, from the opening brace { on line 13 of validatingLogin() to the closing brace } on line 34 is the completion handler.
Thanks, I will study transfer information from button to the completion handler

Here it's my declaration (inside the view):

@State var aspStatus = AspStatus(success: false, message: "")

Here it's my declaration (inside the view):

Thanks. Generally, creating an @State variable of class type would be less useful in many cases. But that depends on many other things. Hope you can find the best solution for your case.
OOPer, you found the solution, I put it inside the completion handler and everything just worked as I needed.
Just a problem of my newer in Swiftui , but I'm growing.......
Thanks again.
Calling a POST Form with URLSession.shared.dataTask
 
 
Q