-1

I am trying to parse the JSON data from my server and I am getting an error when it hits the try! statement and it is crashing. It is telling me

Code=3840 "Invalid value around character 0.

It my be because I have not updated my code correctly to Swift 3. I was having an issue with if let parse for the longest time until I switched the as to as?

@IBAction func registerButtonTapped(_ sender: Any) {

    let userEmail = userEmailTextField.text;
    let userPassword = userPasswordTextField.text;
    let userRepeatPassword = repeatPasswordTextField.text;

    // Check for empty fields
    if((userEmail?.isEmpty)! || (userPassword?.isEmpty)! || (userRepeatPassword?.isEmpty)!){

        //Display alert message

        displayMyAlertMessage(userMessage: "All fields are required");

        return;
    }

    //Check if passwords matech
    if(userPassword != userRepeatPassword){

        // Display alert message
        displayMyAlertMessage(userMessage: "Passwords do not match");
        return;
    }

    // Send user data to server side
    let myUrl = URL(string: "http://");
    let request = NSMutableURLRequest(url:myUrl!);
    request.httpMethod = "Post";

    let postString = "email=\(userEmail)&password=\(userPassword)";

    //adding the parameters to request body
    request.httpBody = postString.data(using: String.Encoding.utf8);

    //creating a task to send the post request
    let task = URLSession.shared.dataTask(with: request as URLRequest){
        data, response, error in

        if error != nil{
            print("error=\(error)")
            return
        }

        //parsing the reponse

        //converting response to Any
        let json = try! JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) as? [String:Any]

        //parsing JSON
        if let parseJSON = json{
            let resultValue = parseJSON["status"] as? String
            print("result: \resultValue)")

            var isUserRegistered:Bool = false;
            if(resultValue=="Success") { isUserRegistered = true;}

            var messageToDisplay:String = parseJSON["messsage"] as! String;
            if(!isUserRegistered)
            {
                messageToDisplay = parseJSON["message"] as! String;
            }

            DispatchQueue.main.async {

                //Display alert message with confirmation.
                let myAlert = UIAlertController(title:"Alert", message:messageToDisplay, preferredStyle: UIAlertControllerStyle.alert);

                let okAction = UIAlertAction(title:"ok", style:UIAlertActionStyle.default){ action in
                    self.dismiss(animated: true, completion:nil);
                }

                myAlert.addAction(okAction);
                self.present(myAlert, animated:true, completion:nil);
            };
        }
    }

    task.resume()

}

Please help, thanks

vadian
  • 274,689
  • 30
  • 353
  • 361
  • 1
    The json you are trying to parse is invalid! Don't use `try! JSONSerialization.jsonObject(...)` - what happens if your sever has a downtime / maintenance / some error which does not produce valid json? Answer: your app will crash :( – luk2302 Dec 21 '16 at 16:54
  • 2
    An exclamation mark invites you: *Please crash me!* It's up to you to catch the error. You are using too many exclamation and question marks anyway. – vadian Dec 21 '16 at 16:55
  • 2
    Possible duplicate of [What does “fatal error: unexpectedly found nil while unwrapping an Optional value” mean?](http://stackoverflow.com/questions/32170456/what-does-fatal-error-unexpectedly-found-nil-while-unwrapping-an-optional-valu) (specifically, for you, the chapter about `try/try?/try!`). – Eric Aya Dec 21 '16 at 16:58
  • I tried dropping the the ! from the try and it throws an error with the let task URL section. I even tried encompassing the whole section in a do statement to catch the error but it doesn't work either. – Jacob Blacksten Dec 21 '16 at 17:03
  • 1
    "I even tried encompassing the whole section in a do statement" - worst idea EVER. First: you cannot catch these kind of exceptions, secondly: fix your code, dont be that guy and just catch the bugs you are introducing yourself into the code. And PLEASE do some debugging. – luk2302 Dec 21 '16 at 17:28

1 Answers1

0

The reason of the error is that you are sending literal "Optional(Foo)" strings to the server via String Interpolation. userEmail and userPassword will never match and the server sends no data back. In Swift 3 you have to explicitly unwrap even implicit unwrapped optional strings.

The solution is a waterproof error handling with optional bindings

@IBAction func registerButtonTapped(_ sender: AnyObject) {

   // Check for empty fields
   guard let userEmail = userEmailTextField.text, !userEmail.isEmpty,
       let userPassword = userPasswordTextField.text, !userPassword.isEmpty,
       let userRepeatPassword = repeatPasswordTextField.text, !userRepeatPassword.isEmpty else {

          //Display alert message
          displayMyAlertMessage(userMessage: "All fields are required")
          return
   }
...

Now all relevant optionals are safely unwrapped and the server will get the right data.

Further trailing semicolons and parentheses around if conditions are not needed in Swift and use URLRequest rather than NSMutableURLRequest in Swift 3

var request = URLRequest(url:myUrl!) // var is mandatory if properties are going to be changed.

PS: In any case – as already mentioned in the comments – never use carelessly try! when receiving data from a server.

vadian
  • 274,689
  • 30
  • 353
  • 361