simplyi / user-registration

23 stars 14 forks source link

Error while signing up. #1

Closed robert1993 closed 4 years ago

robert1993 commented 4 years ago

Hi!

First of all, thank you very much for the great content you make!

I had to write a php json web service to be able to run in on my server. but it gives me the following error which I don't understand:

Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}

PHP states: [Tue Mar 31 17:05:18.146020 2020] [core:error] [pid 864871:tid 140039761164032] [client 94.210.205.184:49849] AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.

Can you help ? signupviewcontroller.swift:

` import UIKit

class SignUpViewController: UIViewController {

@IBOutlet weak var FirstNameTextField: UITextField!
@IBOutlet weak var LastNameTextField: UITextField!
@IBOutlet weak var EmailTextField: UITextField!
@IBOutlet weak var PasswordTextField: UITextField!
@IBOutlet weak var RepeatTextField: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
}

@IBAction func SignUpButtonTapped(_ sender: Any) {
    print("Sign Up Button Tapped")

    if  FirstNameTextField.text!.isEmpty ||
        LastNameTextField.text!.isEmpty ||
        EmailTextField.text!.isEmpty ||
        PasswordTextField.text!.isEmpty ||
        RepeatTextField.text!.isEmpty

    { //(Then) display allert message and return
        displayMessage(userMessage: "Fill in all fields")
        return
    }

    // Validate passowrd
    if ((PasswordTextField.text?.elementsEqual(RepeatTextField.text!)) != true)
    {
        //(Then, alert message and return
        displayMessage(userMessage: "Passwords don't match")
        return
    }

    //Create Activity indicator
        let myActivityIndicator = UIActivityIndicatorView(style:UIActivityIndicatorView.Style.medium)
    // Position activity indicator in ithe center of the main view
    myActivityIndicator.center = view.center

    //If needed, you can prevent actitivty indicator from hiding when stopAnimating() is calles
    myActivityIndicator.hidesWhenStopped = false

    //Start activity indicator
    myActivityIndicator.startAnimating()
    view.addSubview(myActivityIndicator)

    //http request to register user
       let myUrl = URL(string: "*****Blanked out**********/create.php") //**Https** url

 var request = URLRequest(url:myUrl!)
               request.httpMethod = "POST"// Compose a query string
               request.addValue("application/json", forHTTPHeaderField: "content-type")
               request.addValue("application/json", forHTTPHeaderField: "Accept")

    let postString = [ "UID": "",                                 "firstName": FirstNameTextField.text!,
                                    "lastName": LastNameTextField.text!,
                                    "userName": EmailTextField.text!,
                                    "userPassword": PasswordTextField.text!,
                                  ] as [String: String]
             print(postString)
               do {
                   request.httpBody = try JSONSerialization.data(withJSONObject: postString, options: .prettyPrinted)
                print(JSONSerialization.data)
               } catch let error {
                   print(error.localizedDescription)
                   displayMessage(userMessage: "Something went wrong. Try again.")
                   return
               }

            let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in

               self.removeActivityIndicator(activityIndicator: myActivityIndicator)

               if error != nil
               {
                   self.displayMessage(userMessage: "Could not successfully perform this request. Please try again later")
                   print("error=\(String(describing: error))")
                   return
               }

               //Let's convert response sent from a server side code to a NSDictionary object:
               do {
                let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary

                   if let parseJSON = json {

                       let userId = parseJSON["uid"] as? String
                       print("User id: \(String(describing: userId!))")

                       if (userId?.isEmpty)!
                       {
                           // Display an Alert dialog with a friendly error message
                           self.displayMessage(userMessage: "Could not successfully perform this request. Please try again later ofzo")
                           return
                       } else {
                           self.displayMessage(userMessage: "Successfully Registered a New Account. Please proceed to Sign in")
                       }

                   } else {
                       //Display an Alert dialog with a friendly error message
                       self.displayMessage(userMessage: "Could not successfully perform this request. Please try again later ofzo 1")
                   }
               } catch {

                   self.removeActivityIndicator(activityIndicator: myActivityIndicator)

                   // Display an Alert dialog with a friendly error message
                   self.displayMessage(userMessage: "Could not successfully perform this request. Please try again later ofzo 2")
                   print(error)
               }
               }

               task.resume()

           }

             func removeActivityIndicator(activityIndicator: UIActivityIndicatorView)
               {
                   DispatchQueue.main.async
                    {
                           activityIndicator.stopAnimating()
                           activityIndicator.removeFromSuperview()
                   }
               }

           func displayMessage(userMessage:String) -> Void {
               DispatchQueue.main.async
                   {
                       let alertController = UIAlertController(title: "Alert", message: userMessage, preferredStyle: .alert)

                       let OKAction = UIAlertAction(title: "OK", style: .default) { (action:UIAlertAction!) in
                           // Code in this block will trigger when OK button tapped.
                           print("Ok button tapped")
                           DispatchQueue.main.async
                               {
                                  // self.dismiss(animated: true, completion: nil)
                           }
                       }
                       alertController.addAction(OKAction)
                       self.present(alertController, animated: true, completion:nil)
               }
           }

       }

`

simplyi commented 4 years ago

@robert1993 Hi Robert! This error message takes place when a server-side script does not return a valid JSON model. Most likely, there is an error that takes place in PHP script and it sends back an error description plain text rather than a JSON model that Swift script expects. Try sending this HTTP request with a Postman HTTP client or in your Swift script convert the response data to String to see what came back from the PHP script.

robert1993 commented 4 years ago

Hi Sergey! Thank you for your quick respons. When I post something with Postmen to my webservice it returns valid json:

{
    "uid": "128"
}

With the UID which I want to use in the swift code. I'm looking at it for hours now but pretty lost in the wood ;)

simplyi commented 4 years ago

@robert1993 try making your PHP script return this JSON:

{\"uid\":\"128\"}

Will it work?

robert1993 commented 4 years ago

Too bad, Tried both {\"uid\":\"148\"} as [{\"uid\":\"148\"}]

simplyi commented 4 years ago

Have you tried with the backslashes to escape the double quotes?

{\"uid\":\"128\"}

robert1993 commented 4 years ago

O sorry, yes tried that as well, copied the wrong return :)

robert1993 commented 4 years ago

The app displays this error message when I try it:

` self.removeActivityIndicator(activityIndicator: myActivityIndicator)

               // Display an Alert dialog with a friendly error message
               self.displayMessage(userMessage: "Could not successfully perform this request. Please try again later ofzo 2")
               print(error)`
simplyi commented 4 years ago

In your Swift code, try converting the received Data object to String and then printing it:

let str = String(decoding: data, as: UTF8.self) print(str) what will it print?

Add this code right before, converting data to NSDictionary.

robert1993 commented 4 years ago

Aah, it does. It prints: ' <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">

500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at webmaster@******* to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.

`

This is the output of print(postString) ["firstName": "test", "userPassword": "test", "UID": "", "lastName": "test", "userName": "test"] But that seems oke to me? It is the wrong order though, and also different from the code order...

Once again thank you so much for spending your time helping me !

simplyi commented 4 years ago

No, but it also returns a 500 error. All together the returned String is not a valid JSON. There is an issue with the PHP script. In your earlier message, you have mentioned that PHP states:

" Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. "

Do you see this error in a log file? Do you know what are those internal redirects? Why are there so many redirects?

robert1993 commented 4 years ago

Damn me! instead of the url api/users/create.php it had tot be api/user/create.php So sorry for bothering you, but now it works like a charm !

Had to remove the backlashes btw ;)

simplyi commented 4 years ago

Great, 👍🙂 I am glad it started working now!

robert1993 commented 4 years ago

Hmm still a minor issue. It's only inserting the UID in the db. But I guess I have to have a look at my PHP script for that :)

robert1993 commented 4 years ago

Now I can proceed with your swift tutorial 👍