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.