Send json string as httpBody data using objective c - objective-c

I have been trying to send json string converted to nsdata to http body part.
but i always find that correct value is never passed on to
What i want on server :
{"request":"{\"Files\":[{'FileName':'11111111','FileType':'test'}]}"}
What i receive on server :
{"request":{"Files":[{"FileName":"test.html","FileType":"test"}]}}
Can anybody suggest me what am i doing wrong :
I tried following ways :
Way : 1
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:requestDict1 options:0 error:nil];
NSString* jsonString = [[NSString alloc] initWithBytes:[jsonData bytes] length:[jsonData length] encoding:NSUTF8StringEncoding];
[request setHTTPBody:[jsonString dataUsingEncoding:NSUTF8StringEncoding]];
Way : 2
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:requestDict1 options:0 error:nil];
[request setHTTPBody:jsonData];
Crust is i want to send nsdata format of json tring but i cant get perfect value on the server.
Can anybody suggest me a possible way to achieve this?

Try this one.
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:requestDict1 options:NSJSONWritingPrettyPrinted error:nil];
NSString* jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
[request setHTTPBody:jsonString];

Related

Assign single line json element to label in Objective-c

I'm trying to assign a simple json feed element to a label.
My json feed that looks like this:
[{"code":501,"data":{"req":"0"}}]
My code after I've retrieved it from a url:
NSURLResponse *response;
NSData *POSTReply = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
NSString *theReply = [[NSString alloc] initWithBytes:[POSTReply bytes] length:[POSTReply length] encoding: NSASCIIStringEncoding];
NSLog(#"Reply: %#", theReply);
NSArray* json_object = [NSJSONSerialization
JSONObjectWithData:POSTReply
options:0
error:nil];
NSArray *json_object_line = [json_object objectAtIndex:0];
mainLabel.Text= [json_object_line valueForKey:#"code"];
There is no way I can get this to work. The app simply crashes unless I remove the last 2 lines. I've tried a lot of other options (especially for the last 2 lines) to no avail.
Is there anything I'm doing wrong?
You tried to assign NSNumber to the label's text property. It's a reason of the crash. The proper way is to get a formatted string from JSON field:
NSURLResponse *response;
NSData *POSTReply = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response error:nil];
NSString *theReply = [[NSString alloc] initWithBytes:POSTReply.bytes
length:POSTReply.length
encoding:NSASCIIStringEncoding];
NSArray* json_object = [NSJSONSerialization JSONObjectWithData:POSTReply
options:0
error:nil];
NSDictionary *json_object_line = json_object[0];
mainLabel.text= [NSString stringWithFormat:#"%#", json_object_line[#"code"]];

NSJSONSerialization: treating special characters properly

I want to use online data from a JSON file. It's currently working, but when I use special characters it shows "null". Here's the code I'm using:
NSString *urlString = [NSString stringWithFormat:#"http://belesios.com/burc/koc2.php"];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"%#", json);
NSString *ciktiText = [[NSString alloc] initWithFormat:#"%#", json];
[kocLabel setText:ciktiText];
For example, if my file contains ç or ü, null is returned. What do I need to do?
Try this method to find out what encoding is used when data is pulled from server:
NSStringEncoding encoding;
NSString *jsonString =[NSString stringWithContentsOfURL:URL usedEncoding:&encoding error:&error];
if (error)
NSLog(#"Error: %#", error);
You should check encoding of data returned by the server. Your code is correct but you should add some check if error != nil then don't execute and display or log that.
NSString *jsonString = #"{\"abc\":\"ç or ü\"}";
NSDictionary *jsonObj = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:&error];
NSLog(#"Output: %#", jsonObj);
Output: { abc = "\U00e7 or \U00fc"; } This is how your server response should look like with encoded char if you use Fiddler or some other software to print raw response.
Currently your data looks like where as UTF8 encoded chars should be like \U00e7 = ç

Extract inner json data xcode with NSJSONSerialization

My json response from a URL is:
[
{"status":0,
"id":"26",
"content":"See info field for info",
"time":1347565292761,
"info": {"id":"26",
"name":"Ruti",
"twitterPageFollowers":null,
"facebookPageLikes":null,
"activeEmailClients":1}
}
]
I need to extract from it the following strings:
twitterPageFollowers
facebookPageLikes
activeEmailClients
How can I do it?
I tried parsing like this
NSData *urlData=[NSURLConnection sendSynchronousRequest:serviceRequest returningResponse:nil error:nil ];
NSString *returnString=[[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
NSData *jsonData = [returnString dataUsingEncoding:NSUTF8StringEncoding];
NSArray *json = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
NSDictionary *response = [json objectAtIndex:0];
NSString *info = [response objectForKey:#"info"];
NSData *businessInfoString = [info dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *businessInfo =
[NSJSONSerialization JSONObjectWithData: businessInfoString
options: NSJSONReadingMutableContainers
error: nil];
And the return data is ok, but I get [__NSCFDictionary dataUsingEncoding:unrecognized selector sent to instance for the last NSDictionary creation from info field.
What is wrong or what is the shorter way to retrieve the above fields?
When you retrieve the "info" field using [response objectForKey:#"info"];, you already get an NSDictionary! (and NOT an NSString).
That's why when you try to call dataUsingEncoding: on this object (that you believed was an NSString but is as NSDictionary) you get the exception.
There is no need to retrieve the value of "info" key then converting it to NSData and converting it back a JSONObject, because it is already a JSONObject, namely an NSDictionary in your case. Why bother trying to convert it back and forth, whereas [response objectForKey:#"info"]; already returns that businessInfo dictionary that you expect at the end of your code?

How do i get the modhash and cookie from logging into reddit with the api?

NSString *username = #"username";
NSString *password = #"password";
NSURL *loginurl = [NSURL URLWithString:[NSString stringWithFormat:#"http://www.reddit.com/api/login/%#",username]];
NSMutableURLRequest *loginrequest = [NSMutableURLRequest requestWithURL:loginurl];
[loginrequest setHTTPMethod:#"POST"];
NSData *loginRequestBody = [[NSString stringWithFormat:#"api_type=json&user=%#&passwd=%#",username,password] dataUsingEncoding:NSUTF8StringEncoding];
[loginrequest setHTTPBody:loginRequestBody];
NSURLResponse *loginResponse = NULL;
NSError *loginRequestError = NULL;
NSData *loginResponseData = [NSURLConnection sendSynchronousRequest:loginrequest returningResponse:&loginResponse error:&loginRequestError];
NSString *loginResponseString = [[NSString alloc]initWithData:loginResponseData encoding:NSUTF8StringEncoding];
NSLog(#"%#",loginResponseString);
the NSLog prints this: (with some letters replaced)
{"json": {"errors": [], "data": {"modhash":
"j5hq16ukw2f17a9c153xxxxxxxxxa72ad989c96c904d49a97e", "cookie":
"13986184,2012-07-14T12:41:05,349f968b3089af75978xxxxxxxxxxxx761397ba0"}}}
How do i access the modhash and the cookie? I tried
[loginResponseData valueForKey:#"json"];
but it says that the class is not key value coding-compliant for the key json
loginResponseString is an NSString -- it doesn't know if it has JSON inside. You have to parse this JSON to an NSDictionary then you can use its methods to retrieve response data. Try my JSON parser: http://github.com/H2CO3/CarbonateJSON
Example using my CarbonateJSON library:
NSDictionary *parsedResponse = [loginResponseString parseJson];
NSString *modhash = [[[parsedResponse objectForKey:#"json"] objectForKey:#"data"] objectForKey:#"modhash"];
For anyone looking at this after me, you can check out H2CO3's solution, but I found that the easiest solution was using NSJSONSerialization to do it in a supported fashion.
NSError *error;
NSData *jsonData = [loginResponseString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *loginResults = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSString *modhash = [[[loginResults valueForKey:#"json"] valueForKey:#"data"]valueForKey:#"modhash"];
worked for me.

TOUCHJSON Serialization from NSDictionary

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);
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);
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.
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