Error while trying to connect to UITextFields to API

I am trying to connect my UITextFields to connect to the API Token & Database but im getting this error when I run it.


Error: [Assert] Cannot be called with asCopy = NO on non-main thread.

Error: UI api called on a background thread: -[UITextField setText:] PID: 7515, TID:193240. Thread name: (none), Queue name: NSOperationQueue 0x7fd83457b600 (QOS: UNSPECIFIED), Qos: 0

Please show your code, (including all relevant parts).

Likely, you should put the API call inside a dispatch:


            DispatchQueue.main.async { 
                // call API here. Don't forget self
            }

@IBAction func send(_ sender: Any) {

let postString = "c=\(Pw.text!)&d=\(Email.text!)"

let request = NSMutableURLRequest(url: NSURL(string: "http://www.hscrent.com/....php")! as URL)

request.httpMethod = "POST"

request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "content-type")

request.setValue("application/json", forHTTPHeaderField: "Accept")

request.httpBody = postString.data(using: String.Encoding.utf8)

let task = URLSession.shared.dataTask(with: request as URLRequest) {

(data, response, error) -> Void in

if let unwrappedData = data {

do {

let tokenDictionary:NSDictionary = try JSONSerialization.jsonObject(with: unwrappedData, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary

let token = tokenDictionary["...."] as? String

print(tokenDictionary)

}

catch {

DispatchQueue.main.async { // Correct

self.Email.text = ""

self.Pw.text = ""

}

let alertView = UIAlertController(title: "Login failed", message: "Wrong username or password." as String, preferredStyle:.alert)

let okAction = UIAlertAction(title: "Try Again!", style: .default, handler: nil)

alertView.addAction(okAction)

self.present(alertView, animated: true, completion: nil)

return

}

}

}

task.resume()



}

}


I've tried that and its still not working.

Which line is trying to connect my UITextFields to connect to the API Token & Database and causing the error?

Does not work is not enough a diagnostic.


- Where does it fails

- What do you get

- Waht did you expect ?

- What precise error message if any (same as before ?)


Please, use formatter tool. That helps reference line of code and make it easier to read


@IBAction func send(_ sender: Any) {
     
        let postString = "c=\(Pw.text!)&d=\(Email.text!)"
     
        let request = NSMutableURLRequest(url: NSURL(string: "http://www.hscrent.com/....php")! as URL)
        request.httpMethod = "POST"
        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "content-type")
        request.setValue("application/json", forHTTPHeaderField: "Accept")
        request.httpBody = postString.data(using: String.Encoding.utf8)
        let task = URLSession.shared.dataTask(with: request as URLRequest) {
        (data, response, error) -> Void in
        if let unwrappedData = data {
            do {
                let tokenDictionary:NSDictionary = try JSONSerialization.jsonObject(with: unwrappedData, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
                    
                  let token = tokenDictionary["...."] as? String
                  print(tokenDictionary)
                }
                catch {
                     DispatchQueue.main.async { // Correct
                        self.Email.text = ""
                        self.Pw.text = ""
                     }

                     let alertView = UIAlertController(title: "Login failed", message: "Wrong username or password." as String, preferredStyle:.alert)
                     let okAction = UIAlertAction(title: "Try Again!", style: .default, handler: nil)
                     alertView.addAction(okAction)
                     self.present(alertView, animated: true, completion: nil)
                     return
                    }
                }
            }
            task.resume()
 
    }
}


Line 28 should also be on main thread.

Why do you return on line 29 ?

I expected the code to authenticate the email and password I had given it in the login viewcontroller. I basically put in fake information that wasnt in the database and it still logged me in.


I already have my sign up view controller & PHP file connected to database with phpMyAdmin and its passing through the information. I just want to set up my login view controller so it can authenticate the email & password that was given in the sign up view controller by the user. So do i use the same PHP file or create another one? Is this code guiding me in the right direction?

I basically put in fake information that wasnt in the database and it still logged me in.


Do you get the alert or not ?


Could you add a log :

        let task = URLSession.shared.dataTask(with: request as URLRequest) {
             (data, response, error) -> Void in
                  print("dataTask", data, response, error)
                  if let unwrappedData = data {   

I basically put in fake information that wasnt in the database and it still logged me in.

Then so you have made your PHP side. What sort of response does your PHP code send when getting such fake information?

I am not sure about the 'return' (it won't do anything) but the lines involving the alertView need to be moved inside of the DispatchQueue.main.async justy like the lines involving the .text


When you say 'it didn't work - check out the error message. It is no longer complaining about a UITextField - you fixed that. It is now complaining about the alertView.

Yes, we had the same comments (Apr 22, 2020 12:06 AM)

Yes you did (at 2:06 am from my perspective time-wise). I was redefining (simplifying) your 'also be on main thread' suggestion and pointing out that your original guidance, while 'still not working' had significantly changed the error message therein providing the next 'clue'.

I already have

  1. let task = URLSession.shared.dataTask(with: request as URLRequest) {
  2. (data, response, error) -> Void in
  3. print("dataTask", data, response, error)
  4. if let unwrappedData = data {


The fake information just sends to my database. It doesnt give me an error thats its the wrong login or not registered.

You are not checking `error` passed to the closure of `dataTask`.


And/or your server may be malfunctioning and not retuning the wrong login or not registered error.

Thanks for complementing. However, we don't have the final answer yet…

Have a good day.

okay

Error while trying to connect to UITextFields to API
 
 
Q