swiftnsurlconnection

NSURLConnection response returns 500 Status Code


I am trying to connect to a local node.js server setup and authenticate the user. I keep getting the 500 status code and can't figure out what I am missing. I have tried hitting the server with these credentials from a web browser, and it works as expected.

Note: I do understand I have to use the NSURLSession instead of NSURLConnection, but for now, I need to get this to work.

Here is my code,

func signInUserWithDetails(userName:String,userPassword:String,serverURL:NSURL) {
    let credDic :[String:String]=["user[name]":userName,
                                   "user[password]":userPassword ]
    self.httpMethod="PUT"
    self.httpPath="/account"
    self.expectedStatusCode=201

    self.actualStatusCode=NSNotFound
    self.requestUniqueIdentifier = NSUUID().UUIDString

    let urlComponents = NSURLComponents(URL: serverURL, resolvingAgainstBaseURL: false)!
    urlComponents.path = httpPath
    let formedURL = urlComponents.URL!
    var requestOrg = NSMutableURLRequest(URL: formedURL)

    requestOrg.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    requestOrg.addValue("application/json", forHTTPHeaderField: "Accept")
    requestOrg.HTTPMethod=self.httpMethod!

    print(requestOrg.allHTTPHeaderFields) // Output 1

    do{
        let theJSONData = try NSJSONSerialization.dataWithJSONObject(credDic,options: NSJSONWritingOptions.PrettyPrinted)
        let theJSONText = NSString(data: theJSONData,encoding: NSASCIIStringEncoding)

        requestOrg.HTTPBody = theJSONData;

        let tempD=try NSJSONSerialization.JSONObjectWithData(requestOrg.HTTPBody!, options: []) as? [String:String]
        print("\(tempD)")  //Output 2

    }catch let error as NSError {
        print(error)
    }

   connection = NSURLConnection(request: requestOrg, delegate: self, startImmediately: true)!
}

And I am just printing out the response with this,

func connection(didReceiveResponse: NSURLConnection, didReceiveResponse response: NSURLResponse) {
    print("----------------------didReceiveResponse")
    self.response=response
    print("Response Received:"+"\(self.response)")
    let urlResponse:NSHTTPURLResponse = response as! NSHTTPURLResponse
    let responseCode=urlResponse.statusCode
    self.actualStatusCode=responseCode
}

And the result I get is

Optional(["Accept": "application/json", "Content-Type": "application/x-www-form-urlencoded"])
Optional(["user[password]": "R", "user[name]": "R"])
----------------------didReceiveResponse
Response Received:Optional(<NSHTTPURLResponse: 0x7faba269d440> { URL:   http://localhost:3000/account } { status code: 500, headers {
Connection = "keep-alive";
"Content-Length" = 1464;
"Content-Type" = "application/json";
Date = "Sat, 26 Dec 2015 08:34:45 GMT";
"X-Powered-By" = Express;
} })

And the didReceiveData throws this error

{"error":{"message":"Cannot read property 'name' of undefined","stack":"TypeError: Cannot read property 'name' of undefined\n    at Object.exports.signIn [as handle] ( .......

Solution

  • Status code 500 means, that the server could not process your data and ran into an internal error. This oftentimes is caused by improperly encoded HTTP messages, where the server was unable to catch all possible errors.

    When looking at your code, it becomes immediately apparent:

    You are not sending a properly application/x-www-form-urlencoded encoded data to the server. This is likely the main cause of your problem. The other cause might be, that it's likely not a PUT but a POST method which is required to sign-in.

    But before explaining how you encode your data properly, I would suggest to find out whether your server accepts JSON as content data (application/json). If so, properly encoding the data is much easier: having a JSON object (your variable credDic), simply convert it to JSON as UTF-8 in a NSData container. Then, get the length in bytes, set headers Content-Type and Content-Length accordingly.