0

During server development I was using cURL to test data being posted. Now I’m developing on the client side and the data being returned form the server seems malformed.

First, I’ll show you what I was sending with cURL:

curl -X PUT --data "requests[0][data_dictionary][primary_email_address]=myemail@domain.com&requests[0][data_dictionary][first_name]=First&requests[0][data_dictionary][surname]=Last&requests[0][data_dictionary][password]=mypassword" -k -L https://localhost/rest/v1/account/create

And when I print out the received data I get the following:

Request dictionaries: Array
(
    [0] => Array
        (
            [data_dictionary] => Array
                (
                    [primary_email_address] => myemail@domain.com
                    [first_name] => First
                    [surname] => Last
                    [password] => mypassword
                )

        )

)

This is what I expect. Now the client side:

Here is the dictionary before being turned in to NSData with the NSJSONSerialization class:

["requests": (
        {
        "data_dictionary" =         {
            "first_name" = First;
            password = mypassword;
            "primary_email_address" = "myemail@domain.com";
            surname = Last;
        };
    }
)]

And here is the server’s response:

Request dictionaries: Array
(
    [{
__"requests"_:_] => Array
        (
            [
    {
      "data_dictionary" : {
        "first_name" : "First",
        "primary_email_address" : "myemail@domain.com",
        "surname" : "Last",
        "password" : "mypassword"
      }
    }
  ] => 
        )

)

Then when I try to access the key “requests” naturally the server replied with an undefined offset error.

Here is the function that sends the data to the server. Note, I’ve checked the HTTP method too and it is “PUT” as expected:

public func fetchResponses(completionHandler: FetchResponsesCompletionHandler)
{
    let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration(),
        delegate: self,
        delegateQueue: nil)

    let request = NSMutableURLRequest(URL: requestConfiguration.restURI)
    request.HTTPMethod = requestConfiguration.httpMethod

    if (requestConfiguration.postDictionary != nil)
    {
        print("Dictionary to be posted: \(requestConfiguration.postDictionary!)")


        //  Turn the dictionary in to a JSON NSData object

        let jsonData: NSData

        do
        {
            jsonData = try NSJSONSerialization.dataWithJSONObject(requestConfiguration.postDictionary!, options: [.PrettyPrinted])
        }
        catch let jsonError as NSError
        {
            fatalError("JSON error when encoding request data: \(jsonError)")
        }


        //  Set HTTP Body with the post dictionary's data

        request.HTTPBody = jsonData


        //  Set HTTP headers

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

        request.setValue("\(request.HTTPBody!.length)", forHTTPHeaderField: "Content-Length")
    }


    let task = session.dataTaskWithRequest(request) { (data, response, error) in

        //  Check return values

        if error != nil
        {
            fatalError("Request error: \(error)")
        }



        //  Get JSON data

        let jsonDictionary: NSDictionary

        do {
            jsonDictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as! NSDictionary
        }
        catch let jsonError as NSError
        {
            let responseAsString = NSString(data: data!, encoding: NSUTF8StringEncoding)!

            print("Server return data as string: \(responseAsString)")

            fatalError("JSON Error when decoding response data: \(jsonError)")
        }


        //  Do some stuff with the data


        //      Complete with the client responses

        completionHandler(error: nil, responses: clientResponses)
    }

    task.resume()
}

It’s also worth noting my code currently (I’ve left it out here) and successfully skips authentication with the server’s certificate.

Adam Carter
  • 4,741
  • 5
  • 42
  • 103

1 Answers1

0

Okay, so it turns out the actually I’m sending a JSON object where my server is expecting a parameters string. They’re separate things. In order to fix this I needed to use json_decode( file_get_contents('php://input'), true) in order to get the json object as an associative array.

Adam Carter
  • 4,741
  • 5
  • 42
  • 103