NSData to NSString with JSON response - ios

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.

Related

Html tag in json object

I have started on a new project. It is the first time that I see the following webservice output. This following json object text contains html tags.
I wonder how do you parse it to string or how do you know where the paragraph starts? or do you think that I should contact web service developer guy to fix this?
You can use
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData: responseData options: NSJSONReadingMutableContainers error: &e];
To turn the data into dictionary. Then you can access the value of "icerik" by traversing the dictionary tree with NSArray/NSDictionary. For your case example,
first nest is a dictionary of key "news" with array objects. So you get the the array out of it:
NSArray *newsArray = [JSON objectForKey:#"news"];
Then you get the first news item by getting another dictionary:
NSDictionary *firstNews = [newsArray objectAtIndex:0];
Then you can get icerik:
NSString *icerik = [firstNews objectForKey:#"icerik"];
Once you get the value as string, you need to do some string manipulation on it (many ways to do this)
You can get your html string as
NSDictionary *json = [NSJSONSerialization JSONObjectWithData: responseData options: NSJSONReadingMutableContainers error: &e];
NSString *icerik = json[#"news"][0][#"icerik"];
You can use UIWebView or UITextView to load html string.
NSString *myHTML = [NSString stringWithFormat:#"<html><body>%#</body></html>" ,icerik ];
[yourWebView loadHTMLString:myHTML baseURL:nil];

How to parse JSON data from textual file in Objective-C

I know, JSON parsing questions are asked over and over again, but still I can't find any answer to this one.
I've been trying to read and parse a textual JSON file using NSJSONSerialization to no avail.
I've tried using the same JSON data from a NSString and it did work.
Here's the code:
NSError *error;
NSString *jsonString1 = [NSString stringWithContentsOfFile:jsonFilePath
encoding:NSUTF8StringEncoding
error:&error];
NSData *jsonData1 = [jsonString1 dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonObject1 = [NSJSONSerialization JSONObjectWithData:jsonData1
options:0
error:&error];
NSString *jsonString2 = #"{\"key\":\"value\"}";
NSData *jsonData2 = [jsonString2 dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonObject2 = [NSJSONSerialization JSONObjectWithData:jsonData2
options:0
error:&error];
- The text file contains one line: {"key":"value"}
- jsonString1 = #"{"key":"value"}"
- jsonString2 = #"{\"key\":\"value\"}"
- jsonData1 is 23 bytes in size
- jsonData2 is 15 bytes in size
- jsonObject1 is nil and I get error code 3840
- jsonObject2 is a valid dictionary
Seems like the problem is with reading the file, since the NSStrings and NSDatas differ, but what am I doing wrong here and how can I fix it?
Most likely you file contains some unprintable characters (e.g. \0) that trigger the failure. Printing the error message will tell you at what position the first invalid characters occurs.
For example, try printing "{\"key\":\u{0000}\"value\"}" and you'll seem to get a valid JSON, however decoding it fails.
I always do a check on the return value when doing anything with NSUTF8StringEncoding and if nil, then try NSASCIIStringEncoding:
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
if (jsonString == nil) {
jsonString = [[NSString alloc] initWithData:jsonData encoding:NSASCIIStringEncoding];
}
return jsonString;

Converting NSString to proper JSON format

Converting NSString to proper JSON format..
NSString *input_json = [NSString stringWithFormat:#"{\"id\":\"%#\",\"seconds\":\"%d\",\"buttons\": \"%#\"}", reco_id, interactionTime, json_Buttons];
Here json_Button is in json format converted from nsdictionary..
My input_json result is:
{"id":"119","seconds":"10","buttons": "{
"update" : "2",
"scan" : "4"
}"}
It is not in a proper JSON format. key buttons contain "{}" I want to remove these quotes.
Expected Result is:
{
"id": "119",
"seconds": "10",
"buttons": {
"update": "2",
"scan": "4"
}
}
You are going about this all wrong. First, create an NSDictionary that contains all of the data you want converted to JSON. Then use NSJSONSerialization to properly convert the dictionary to JSON.
Something like this will work:
NSDictionary *dictionary = #{ #"id" : reco_id, #"seconds" : #(interactionTime), #"buttons" : json_Buttons };
NSError *error = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:&error];
if (data) {
NSString *jsonString = [[NSString alloc] intWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"JSON: %#", jsonString);
} else {
NSLog(#"Unable to convert dictionary to JSON: %#", error);
}
It's a bad idea to try to build JSON strings manually. Use the NSJSONSerialization class. That makes it easy. Create your dictionary, then call dataWithJSONObject:options:error:.
If you use options: NSJSONWritingPrettyPrinted it inserts line breaks and whitespace that makes the JSON more readable.
By using that function you get correctly formatted JSON every time, and it's flexible because if you send it a different dictionary you get different JSON.

Fill NSDictionary with JSON [duplicate]

This question already has answers here:
Decode JSON to NSArray or NSDictionary
(5 answers)
Closed 9 years ago.
Iam new in iOS development .
I want to fill this json
"{
"form_name":"login_form_mobile",
"user_login":"mark wallet",
"password":"123456",
"dispatch":{"auth.login":"Sign in"}
}
"
into a NSDictionary to use it in post for a URL using AFNetworking.
I fill the dictionary like this
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:#"login_form_mobile",#"form_name",#"markwallet",#"user_login",#"123456",#"password",#"{ \" auth.login \" : \" Sign in \" }",#"dispatch", nil];
Now i have two problems
1-The \" in before and after auth.login is shown as it i want to show the Double quotes only.
BTW i tried to make a nested Dictionary this solved the first problem but for the second one problem not.
2-When i run the app. and see how the dictionary is filled it is shown like this
{
dispatch = "{ \" auth.login \" : \" Sign in \" }";
"form_name" = "login_form_mobile";
password = 123456;
"user_login" = markwallet;
}
a-There is equal between the key and its value and i need it : not =
b-some words doesnt have "" like password , 123456 and markwallet . i dont know why
c-Also i dont know why dispatch and it value go in the first.
EDIT:
I used this new code.
NSDictionary *dic = [[NSDictionary alloc]initWithObjectsAndKeys:#"Sign in",#"auth.login", nil];
NSArray *keys = [NSArray arrayWithObjects:#"form_name",#"user_login",#"password",#"dispatch",nil];
NSArray *objects = [NSArray arrayWithObjects:#"login_form_mobile",#"markwalletz",#"123456",dic,nil];
NSMutableDictionary * params1 = [[NSMutableDictionary alloc]init];
params1 = [NSMutableDictionary dictionaryWithObjects:objects forKeys:keys];
But when i see params1 value in the debug
{
dispatch = {
"auth.login" = "Sign in";
};
"form_name" = "login_form_mobile";
password = 123456;
"user_login" = markwalletz; }
And this is differs from the one i need as stated at the top of the question
And when i send a request with this dictionary it replies BAD Request.
Several things you need to understand:
When you NSLog an NSDictionary, it does not display JSON syntax. Yes, it superficially looks like JSON, but, as you noted, not all character strings are quoted (only those with blanks or odd characters get quotes) and an = is used instead of :. This is because it's a description of the NSDictionary object, not a JSON translation.
And, on the other hand, just because stuff looks the same between JSON and an NSDictionary does not make it the same. Your "dispatch":{"auth.login":"Sign in"} entry represents a second NSDictonary as the value of the key "dispatch". You cannot create that second dictionary simply by making the characters look like the JSON/description representation. Rather, you have to (as a separate conceptual step) create that one-element dictionary and then insert it as an object in the outer dictionary.
One place where NSDictionary and JSON are the same is that neither an NSDictionary nor a JSON "object" maintains the order of the key/value pairs it contains. So don't expect to see the values in the same order in one version vs the other.
Look at the NSJSONSerialization class. Methods in this class will convert JSON into the appropriate objects (e.g NSDictionary, NSArray), and vice versa. See the Apple Documentation for details.
Added:
For example:
NSString *jsonString = ... // Whatever your JSON is
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *d = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
What you get is a dictionary, d, that contains all the keys and their values as described in the JSON (assuming the JSON represented a dictionary). JSON data can represent an array of objects too. It's all quite flexible. I suggest reading the references documentation and search here for other examples using NSJSONSerialization. There are surely some good ones.
The "jsonString" variable should be formed like:
NSString *jsonString = #"{\"form_name\":\"login_form_mobile\",\"user_login\":\"mark wallet\",\"password\":\"123456\",\"dispatch\":\{\"auth.login\":\"Sign in\"}}";
Then, using the code above:
NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:nil];
NSLog(#"DIC %#",dic);
will output:
DIC {
dispatch = {
"auth.login" = "Sign in";
};
"form_name" = "login_form_mobile";
password = 123456;
"user_login" = "mark wallet";
}
If your json string is in a NSString variable called "jsonString":
NSData *data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments
error:nil];
So your "dic" variable will have the parsed json.

NSJSONSerialization sometimes returns null in async request

I've been developing app, that makes asynchronous requests for JSON type of data. Lately, I found strange bug in my code and I can't tell why it is happening.
Ok to the code!
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSError *error=nil;
result = [NSJSONSerialization JSONObjectWithData:retrievedData options:kNilOptions error:&error];
NSLog(#"Result %#",result);
NSLog(#"Retrieved data %#",retrievedData);
}
Result is NSDictionary, retrievedData is NSMutableData.
99% of the time, it works fine, connectionDidFinishLoading gets called, and my result is populated. However, in that 1% of the time retrieved data is filled with data, but my result is null.(as you can see on the picture. Could anyone help me please?
Edit: I get following error
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Garbage at end.) UserInfo=0x753e5c0 {NSDebugDescription=Garbage at end.}
It would help if you take a look at the error first, to see if that gives any indication of what is wrong.
[edit]
Your error mentions the reason: Garbage at end..
The response from the webserver is not valid JSON, it contains invalid characters at the end of the output.
I had the same issue. First, look what is a data that wasn't parsed correctly - in my case I did
NSString *str = [[NSString alloc] initWithData:retrievedData encoding:NSUTF8StringEncoding];
In my case the reason was - if server sent a few socket.write()'s in a row - all data was received in one single chunk, like
{first:json}{second:json}..
of course this cannot be parsed as one single json, so I have to introduce delimiter, and split the received buffer into correct chunks.
This is a little late but nothing online worked for me until I did this:
NSString * dataInString = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSRange range = [dataInString rangeOfString:#"}" options:NSBackwardsSearch];
if(range.location != NSNotFound)
dataInString = [dataInString substringWithRange:NSMakeRange(0,range.location+1)];
Always worked since then.
I had the same error, the problem was my server was attaching some extra lines to my json response, that would not appear when i will get the response in my browser. Using curl from terminal you can see the actual output.
The hack was to truncate the extra characters. with json either you have an array or dictionary. Depending on your json structure, you can use the code (as above answer) but look for the comment in line 2
NSString * str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSRange range = [str rangeOfString:#"}" options:NSBackwardsSearch]; // } for dictionary, ] for array
if(range.location != NSNotFound)
str = [str substringWithRange:NSMakeRange(0,range.location+1)];
once you get your string clean from garbage data, you can convert it to data again.
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
and now from this data you can get your array or dictionary.
id jsonObject = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions error:&error]; // i used id to be general, you can use array or dictionary structure or later cast this object to as per json

Resources