objective-c: NSJSONSerialization fail when data is from string - objective-c

In my parser I have a method that give back the result object of a API. It fail when the content data is a string:
...
resul = [NSJSONSerialization JSONObjectWithData: data options: NSJSONReadingMutableContainers error: &error];
return resul;
resul is nil.
But data is not nil: if execute :
NSString *strResul = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]
strResul is "MY STRING".
Why NSJSONSerialization fail only in this case?

If the expected result can be NSString you have to pass NSJSONReadingAllowFragments

The string should be in a valid JSON format in order to work
Because NSJSONSerialization will result in an NSArray or an NSDictionary

Your string's format is incorrect. The following string is correct
{
"title": "Team member - sunnyxx",
"content": "Working at Baidu, Zhidao iOS team, weibo: ",
"username": "sunnyxx",
"time": "2015.04.11",
"imageName": "sunnyxx"
}
or you initialize a dictionary and transfer it to jsonString, then use the api to parse it.

Related

JSON: Understanding format in Objective-C

Given the following JSON payload I would like to extract "023" from keyB->key2:
JSON Payload:
{
"keyA" : {"lon": 139, "lat" : 35},
"keyB" : [ {"key1" : "value", "key2" : "023"} ]
}
This is the code I apply:
NSDictionary * subResults = jsonResult[#"keyB"];
NSLog(#"VALUE: %#", [subResults valueForKey:#"key2"])
However the value is printed as following:
VALUE: (
023
)
I want to get rid of the brackets "(". Am I approaching the extraction in the wrong way?
First, your json as given is not valid son :( you have a quote to many. If we escape it like this:
{"keyA":{"lon":139,"lat":35},"keyB":[{"key1":"value\" clouds","key2":"023"}]}
Then, it's ok.
Now, what you have here is an son object, containing 2 keys (A and B). And KeyB is associated with a json Array
meaning :
jsonResult[#"keyB"];
Does not return a NSDictionnary but a NSArray, containing 1 NSDictionary.
Now if you try to get the value "023", you should use
NSString str = jsonResult[#"keyB"][0][#"key2"]; // return "023"
and maybe
int twentyThree = str.intValue;
The brackets show the value you want is inside an array.
NSData strAsData = …;
NSDictionary *jsonResult = [NSJSONSerialization JSONObjectWithData:strAsData options:0 error:nil];
NSArray *subResults = jsonResult[#"keyB"];
NSDictionary *subSubResults = subResults[0];
NSLog(#"VALUE: %#", subSubResults[#"key2"]);
Because the array only has one item you can use a call to -lastObject or -firstObject

Any shortcut or open source code can format a JSON String with proper indentation in Objective-C

Problem:
Every time, when I got a JSON string from Web Server, it looks like this:
{"array":[1,2,3],"boolean":true,"null":null,"number":123,"object":{"a":"b","c":"d","e":"f"},"string":"Hello World"}
I really wanna re-organise string format to NSLog() it like this:
{
"array": [
1,
2,
3
],
"boolean": true,
"null": null,
"number": 123,
"object": {
"a": "b",
"c": "d",
"e": "f"
},
"string": "Hello World"
}
Question:
Is there any shortcut to format JSON NSString with proper indentation and line feeds? (I know [NSDictionary description])
P.S.
Sometimes, the JSON NSString has prefix string like this:
Web Service response is : {"array":[1,2,3],"boolean":true,"null":null,"number":123,"object":{"a":"b","c":"d","e":"f"},"string":"Hello World"}
Any method or regular-expression can grab JSON string out of the paragraph?
Try this
NSData *data = [NSJSONSerialization dataWithJSONObject:temp options:NSJSONWritingPrettyPrinted error:nil ];
NSString* aStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"result: %#", aStr);
Here's some code that will strip leading characters up to the first curly brace and display the JSON data nicely formatted on the debug console.
NSRange range = [str rangeOfString:#"{"];
if ( range.location != NSNotFound )
str = [str substringFromIndex:range.location];
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
id jsonData = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog( #"%#", jsonData );
Try to parse it to an Object first and see what happens if you print it then. With a little luck the textual representation of Array's and Dictionaries will get you on your way. Right now you are printing a string, which will always look a little something like that.
Obviously you could write some code that recognizes the curly brackets and commas and based on that adds in line-endings and indentations. Should not be too hard, but the question is why would you want that?
If you use it to debug, just put a breakpoint there and look at the object in your code in XCode with the inspector. That will show you the object and the objects withing and give you an option to print it's representation to the console.

Web Service JSON nsdictionary unicode string [duplicate]

NSData* jsonData is the http response contains JSON data.
NSString* jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"jsonString: %#", jsonString);
I got the result:
{ "result": "\u8aaa" }
What is the proper way to encoding the data to the correct string, not unicode string like "\uxxxx"?
If you convert the JSON data
{ "result" : "\u8aaa" }
to a NSDictionary (e.g. using NSJSONSerialization) and print the dictionary
NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSLog(#"%#", jsonDict);
then you will get the output
{
result = "\U8aaa";
}
The reason is that the description method of NSDictionary uses "\Unnnn" escape sequences
for all non-ASCII characters. But that is only for display in the console, the dictionary is correct!
If you print the value of the key
NSLog(#"%#", [jsonDict objectForKey:#"result"]);
then you will get the expected output
說
I don't quite understand what the problem is. AFNetworking has given you a valid JSON packet. If you want the above code to output the character instead of the \u… escape sequence, you should coax the server feeding you the result to change its output. But this shouldn't be necessary. What you most likely want to do next is run it through a JSON deserializer…
NSDictionary * data = [NSJSONSerialization JSONObjectWithData:jsonData …];
…and you should get the following dictionary back: #{#"result":#"說"}. Note that the result key holds a string with a single character, which I'm guessing is what you want.
BTW: In future, I suggest you copy-paste output into your question rather than transcribing it by hand. It'll avoid several needless rounds of corrections and confusion.

Converting NSStrings to Json

I have search a lot ,i did found many answers, but not the specific one i need-which is so simple.
I want to take 2 different NSString that the user type, and create a json from them to send to server .
I wrote this :
-(id)stringToJason:(NSString*)stringData
{
NSData *data = [stringData dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
return json;
}
But there is something i dont get. this return 1 nsstring as json.
How would i take 2 different NSStrings, and create from them together ,the json ?
Lets say: userName:me (when each one is comes from text field)
json should look like :
"Username": "me",
"Firstname": "r",
"Lastname": "k",
If you're wanting to produce JSON that looks like:
{
"Username":"me",
"Firstname":"r",
"Lastname":"k"
}
Where r and k are values taken from the textfields, you could write a method along the lines of this:
-(NSData*)jsonFromFirstName:(NSString*)firstName andLastName:(NSString*)lastName
{
NSDictionary* dic = #{#"Username" : #"me", #"Firstname" : firstName, #"Lastname" : lastName};
// In production code, _check_for_errors!
NSData* json = [NSJSONSerialization dataWithJSONObject:dic options:0 error:nil];
return json;
}
You would call this method, passing the r (firstName) and k (lastName) values to it. It would construct a dictionary that has the structure of the desired JSON, with the desired values. You'd then use NSJSONSerialization's -dataWithJSONObject:options:error selector to convert the dictionary into a JSON data object (stored in an NSData object). You then have the data to send to the server!
The dictionary created in the first line of the method could be expanded as much as you desired, and you could even pass in non-strings (such as numbers, arrays, or even other dictionaries!).

How to parse a JSON having no quotes with its KEY string?

I want to parse the json output resulting from the following url in SBJSON framework for iOS
http://maps.google.com/maps?q=school&mrt=yp&sll=13.006389,80.2575&output=json
while(1);{title:"school - Google Maps",url:"/maps?q=school\x26mrt=yp\x26sll=13.006389,80.2575\x26ie=UTF8\x26hq=school\x26hnear=",urlViewport:false,ei:"RCu3T4eeMqSiiAe7k-yZDQ",form:{selected:"q",q:{q:"school",mrt:"yp",what:"school",near:""},d:{saddr:"",daddr:"",dfaddr:""},geocode:""},
I am using http://www.bodurov.com/JsonFormatter/ to read it online.
In ASIHttpRequest response method I removed while(1); from the response
NSString *responseString = [[request resonseString]substringFromIndex:9]; //to remove while(1)
SBJSONParser * parser = [[SBJSONParser alloc]init];
NSDictionary *jsonDict = (NSDictionary*)[parser objectFromString:responseString];
NSLog(#"%#",jsonDict) // prints null
// [responseString JSONValue] also reports error
I guess JSON key without double quotes is causing problem.
Instead of {
"title": "hospital - Google Maps",
"urlViewport": false,
}, we get {
title: "hospital - Google Maps",
"urlViewport": false
}
Please help me to parse this complex JSON structure returned from Google.
This worked better for my case because my values contained times which caused the regular expression in the above answer to match incorrectly.
json = [json stringByReplacingOccurrencesOfString: #"(\\w*[A-Za-z]\\w*)\\s*:"
withString: #"\"$1\":"
options: NSRegularExpressionSearch
range: NSMakeRange(0, json.length)];
You need to add the missing quotes to the keys, so try this:
responseString = [responseString stringByReplacingOccurrencesOfString:#"(\\w+)\\s*:"
withString:#"\"$1\":"
options:NSRegularExpressionSearch
range:NSMakeRange(0, [responseString length])];
This should work well with the given JSON string.