1

I've read through the questions and answers related to TouchJSON serialization and I'm still not getting it to work.

I create an NSDictionary with sample data and used the JSONTouch serializer to convert the NSDictionary to JSON. However, when I log the NSData object 'theJSONData', it gives me this as a result:

<7b223131 31353535 34343434 223a2250 ... 65227d>

Additionally, when I send this 'theJSONData' data to the web service (that's expecting JSON) this is what I get back:

2011-07-31 18:48:46.572 Street Lights[7169:207] Serialization Error: (null)

2011-07-31 18:48:46.804 Street Lights[7169:207] returnData: (null)

2011-07-31 18:48:46.805 Street Lights[7169:207] Error: Error Domain=kJSONScannerErrorDomain Code=-201 "Could not scan array. Array not started by a '[' character." UserInfo=0x4d51ab0 {snippet=!HERE>!?xml version="1.0" , location=0, NSLocalizedDescription=Could not scan array. Array not started by a '[' character., character=0, line=0}

What am I doing wrong? Does the JSON NSData object 'theJSONData' need to be converted to another type before I send it to the web service? Is there another step I'm missing?

// Create the dictionary
NSDictionary *outage = [[NSDictionary alloc] initWithObjectsAndKeys:
                        @"YCoord", @"12678967.543233",
                        @"XCoord", @"12678967.543233",
                        @"StreetLightID", @"666",
                        @"StreetLightCondition", @"Let's just say 'BAD'",
                        @"PhoneNumber", @"1115554444",
                        @"LastName", @"Smith",
                        @"Image",@"",
                        @"FirstName", @"Dawn",
                        @"Comments", @"Pole knocked down",
                        nil];
NSError *error = NULL;

// Serialize the data
NSData *theJSONData = [[CJSONSerializer serializer] serializeDictionary:outage error:&error];
NSLog(@"theJSONData: %@", theJSONData);
NSLog(@"Serialization Error: %@", error);

// Set up the request and send it
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: @"http://24.52.35.127:81/StreetLight/StreetlightService/CreateStreetLightOutage"]];
[request setHTTPMethod: @"POST"];
[request setHTTPBody: theJSONData];

// Deserialize the response
NSData *returnData = [ NSURLConnection sendSynchronousRequest: request returningResponse: nil error:&error];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding: NSUTF8StringEncoding];
NSData *theReturnData = [returnString dataUsingEncoding:NSUTF8StringEncoding];
id theObject = [[CJSONDeserializer deserializer] deserializeAsArray:theReturnData error:&error];
NSLog(@"returnData: %@",theObject);
NSLog(@"Error: %@", error);
Dawn J
  • 21
  • 4
  • Two quick things: 1) you probably want to reverse your nsdictionary defs (it's ObjectsAndKeys, not KeysAndObjects), and 2) use a program like Http Client to see what your server returns. It sounds like your server doesn't like what you send, and returns nothing, which gives you the error. Just a guess. – Colin Aug 01 '11 at 02:31

3 Answers3

1

Thanks for everyone's help. I ended up using Fiddler to track what needed to be sent to the service in JSON and then saw I hadn't been formatting the header correctly. Here is the code that ended up working for me.

// Create the NSDictionary
NSDictionary *outage = [[NSDictionary alloc] initWithObjectsAndKeys:
                        @"12.543233",@"YCoord", 
                        @"12.543233",@"XCoord", 
                        @"111",@"StreetLightID",
                        @"Dented pole",@"StreetLightCondition", 
                        @"1115554444",@"PhoneNumber", 
                        @"Black",@"LastName", 
                        [NSNull null],@"Image",
                        @"White",@"FirstName", 
                        @"Hit by a car",@"Comments", 
                        nil];

// Serialize the data
NSError *error = NULL;
NSData *theJSONData = [[CJSONSerializer serializer] serializeDictionary:outage error:&error];
NSLog(@"Serialization Error: %@", error);

// Change the data back to a string
NSString* theStringObject = [[NSString alloc] initWithData:theJSONData encoding:NSUTF8StringEncoding];

// Determine the length of the data
NSData *requestData = [NSData dataWithBytes: [theStringObject UTF8String] length: [theStringObject length]];
NSString* requestDataLengthString = [[NSString alloc] initWithFormat:@"%d", [requestData length]];

// Create request to send to web service
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString: @"http://11.22.33.444:55/StreetLight/StreetlightService/CreateStreetLightOutage"]];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:requestData];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setValue:requestDataLengthString forHTTPHeaderField:@"Content-Length"];
[request setTimeoutInterval:30.0];

// Deserialize the response
NSData *returnData = [ NSURLConnection sendSynchronousRequest: request returningResponse: nil error:&error];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding: NSUTF8StringEncoding];
NSData *theReturnData = [returnString dataUsingEncoding:NSUTF8StringEncoding];

id theObject = [[CJSONDeserializer deserializer] deserializeAsArray:theReturnData error:&error];

NSLog(@"returnData: %@",returnString);
NSLog(@"Error: %@", error);
Dawn J
  • 21
  • 4
0

For one thing, you've got your objects and keys reversed in the NSDictionary.

I don't know enough about TouchJSON to help with that part of the code.

EricS
  • 9,650
  • 2
  • 38
  • 34
  • Thanks all- I figured out my problem. I used Fiddler to track what needed to be send and I realized I wasn't formatting the header correctly. Here's the code that ended up working for me: – Dawn J Aug 06 '11 at 21:45
0

I am having similar issues in parsing a goodle v3 api response. Still no closer to resolving my issue, but one thing I have found that may be helpful to you is if you are using the deserializerAsArray then the JSON response must be enclose in "[" and "]" and if you are deserializerAsDictionary then the JSON response must be enclosed in "{" and "}".

As the google v3 api JSON response is in the "{" "}" format I need to use deserialiserAsDictionary method.

I suspect you know this already, but after looking at Jonathan Wight's code this is as far as I have come in resolving my own issue as Jonathan's code is specific in checking for the above in parsing the JSON response.

Thanks,

Tim

timv
  • 3,346
  • 4
  • 34
  • 43
  • Hi, my problem is the fact that i did not allow for the data to fully download from the internet before parsing it. I simply forgot about the synchronous vs asynchronous NSURL issue. Apologies for the red herring. – timv Aug 03 '11 at 23:17
  • yep, fixed by using asynchronous and it parses just fine. Heres the link to the info I used to fix my issue: http://www.cocoabyss.com/foundation/nsurlconnection-synchronous-asynchronous/ – timv Aug 04 '11 at 00:10