NSJSONSerialization JSONObjectWithData where data contains line break characters - ios

Sample Code:
NSString *jsonObject = ...;
BOOL isValidJSONObject = [NSJSONSerialization isValidJSONObject:jsonObject];
id jsonResponse = [NSJSONSerialization JSONObjectWithData:parsedData
options:NSJSONReadingAllowFragments
error:&jsonError];
Issue:
If jsonObject contains string data with newline characters, then NSJSONSerialization fails to parse and return a valid jsonRespone object. It returns following error:
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Unescaped control character around character 119.) UserInfo=0x10ba9fef0 {NSDebugDescription=Unescaped control character around character 119.}
Sample JSON String (with newline character):
{"Name" : "Lorum","Description" : "Sample:
Lorum ipsum","Quantity" : 1,"Type" : 1}
What's the best way to handle this situation? Newline/ line break character should be valid in this case.

YES, double backslash is needed. However slash is not need to write twice.
For example,
jsonString = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:#[#"line 0\nline1", #"http://twitter.com"] options:0 error:nil] encoding:NSUTF8StringEncoding];
when hover your cursor on jsonString, Xcode will tell you what it exactly want. If you write
jsonString = #"[\"http://twitter.com\"]",
you can get correct answer when using NSJSONSerialization to parse the string. Even you know the more suitable input is
jsonString = #"[\"http:\\/\\/twitter.com\"]".

Related

Error Domain=NSCocoaErrorDomain Code=3840 "Invalid escape sequence around character 746."

I am getting this error
Error Domain=NSCocoaErrorDomain Code=3840 "Invalid escape sequence around character 746." UserInfo={NSDebugDescription=Invalid escape sequence around character 746.}
Here is my code to parse JSON:
NSString *strResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
strResponse=[self stringByRemovingControlCharacters:strResponse];
NSData *jsonData = [strResponse dataUsingEncoding:NSUTF8StringEncoding];
responseObject = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&serializationError
Using this code I am getting response object in other API.
but in my API contains HTML tags.
My issue is I am getting JSON string but it is not parsing in JSON.
for this API I am getting error
"Error Domain=NSCocoaErrorDomain Code=3840".
My conclusion is that JSON is not parsing properly in above code.
The string from Ur backend may be invalid JSON,it may contain "\s""\n""\t" or other tab character。And in Xcode u print it will not see the tab character,the console will not print them.You may get the JSON and find if there are tab characters.

Converting JSON string into object

I am trying to convert a JSON string into an object in Objective C using the code:
NSString *jsonString = (NSString *) responseObject;
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
The value of jsonString is
"[{\"Date\": \"12-01-2015\", \"Time\": \"7:00 am\", \"Title\":
\"First Car Service\", \"Details\": \"This was the first car
service ever done\"}]"
But the value of json is always nil. How do I convert the jsonString into a NSArray ?
My (third) bet: your json string isn't correct. If it contains the leading and trailing quotes strip them. Replaced the \" with ".
better: make the server or other json source send correct json.
From the error, it may be that your string is not formatted correctly, probably due to the quotes.
You should also make sure that after you have formatted the string, then you check the array has objects.
NSLog(#"JSON Details: %#", json[0][#"Details"]);

Need some help to convert JSON string to NSDictionary

How do I convert this NSString to NSDictionary? Below is the NSString:
NSLog(#"urlstring: %#", urlString);
outputs: urlstring: "{"url":"http://mydomain.com/metaioman_target.png"}"
Then I convert it to JSON and then to NSDictionary:
NSData *json = [urlString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:json options:0 error:&e];
However, when I NSLog the dic it is null, and printing the error gives the following:
error: Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)"
(JSON text did not start with array or object and option to allow fragments not set.)
UserInfo=0x16641de0 {NSDebugDescription=JSON text did not start with
array or object and option to allow fragments not set.}
However, overwriting the urlString with:
#"{\"ID\":\"Content\":268,\"type\":\"text\"},\"ContractTemplateID\":\"Content\":65,\"type\":\"text\"}}"
converts it successfully.
I guess something is wrong with the quotes?
If your string was valid (in terms of JSON) NSLog should output:
urlstring: {"url":"http://mydomain.com/metaioman_target.png"}
so your problem is the outer double quotes, get rid of them and it will deserialize just fine.
You have double quotes around the actual JSON string.
You need to check when these quotes are added and get rid of them.
urlString should be {"url":"http://mydomain.com/metaioman_target.png"} instead of "{"url":"http://mydomain.com/metaioman_target.png"}"
Or you can remove them before you deserialize:
[urlString substringWithRange:NSMakeRange(1, [urlString length]-2)]

How to convert UTF8String to JSON based NSDictionary?

I am getting one of my web-service response in JSON. Here is the UTF8String base responseString:
"{\"ApplicationId\":1,\"CurrentPosition\":0,\"EndOfFile\":false,\"Media\":{\"Active\":true,\"Description\":\"This video demonstrates a quick overview of Bentley LEARN Server.\",\"LocationId\":1,\"MP4URL\":\"http:\\/\\/cdnllnw.bentley.com\\/s\\/LearnVideo\\/Welcome.mp4?s=1380034262&e=1380077462&h=c2641922fd862ffe5c5a05e94786359a\",\"MediaId\":5003235,\"MediaURL\":\"http:\\/\\/cdnllnw.bentley.com\\/s\\/LearnVideo\\/Welcome.mp4?s=1380034262&e=1380077462&h=c2641922fd862ffe5c5a05e94786359a\",\"StreamServer\":null,\"Title\":\"Welcome\",\"TransferStatus\":0,\"filesize\":9094429},\"MediaDuration\":0,\"SkippedCurrentPosition\":0,\"UserBP\":8011512,\"ViewedTime\":0}"
After formatting it looks like:
{
"ApplicationId":1,
"CurrentPosition":0,
"EndOfFile":false,
"Media":
{
"Active":true,
"Description":"This video demonstrates a quick overview of Bentley LEARN Server.",
"LocationId":1,
"MP4URL":"http:\/\/cdnllnw.bentley.com\/s\/LearnVideo\/Welcome.mp4?s=1380035311&e=1380078511&h=d8de8ade046266fb7324be90a575f978",
"MediaId":5003235,
"MediaURL":"http:\/\/cdnllnw.bentley.com\/s\/LearnVideo\/Welcome.mp4?s=1380035311&e=1380078511&h=d8de8ade046266fb7324be90a575f978",
"StreamServer":null,
"Title":"Welcome",
"TransferStatus":0,
"filesize":9094429
},
"MediaDuration":0,
"SkippedCurrentPosition":0,
"UserBP":8011512,
"ViewedTime":0
}
How can I convert this string into JSON object or NSDictionary object so that I can access all key-values easily.
I have tried this:
NSString *responseString = [NSString stringWithUTF8String:response.c_str()];
NSDictionary *JSONdict =
[NSJSONSerialization JSONObjectWithData: [responseString dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: &error];
But it says JSONdict is nil and error description is:
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.) UserInfo=0xd8bbd30 {NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
Please help
Adding NSJSONReadingAllowFragments as option should help according to error:
NSString* jsonString = #"{\"ApplicationId\":1,\"CurrentPosition\":0,\"EndOfFile\":false,\"Media\":{\"Active\":true,\"Description\":\"This video demonstrates a quick overview of Bentley LEARN Server.\",\"LocationId\":1,\"MP4URL\":\"http:\\/\\/cdnllnw.bentley.com\\/s\\/LearnVideo\\/Welcome.mp4?s=1380034262&e=1380077462&h=c2641922fd862ffe5c5a05e94786359a\",\"MediaId\":5003235,\"MediaURL\":\"http:\\/\\/cdnllnw.bentley.com\\/s\\/LearnVideo\\/Welcome.mp4?s=1380034262&e=1380077462&h=c2641922fd862ffe5c5a05e94786359a\",\"StreamServer\":null,\"Title\":\"Welcome\",\"TransferStatus\":0,\"filesize\":9094429},\"MediaDuration\":0,\"SkippedCurrentPosition\":0,\"UserBP\":8011512,\"ViewedTime\":0}";
NSError* error = nil;
NSDictionary *JSONdict =
[NSJSONSerialization JSONObjectWithData: [responseString dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers | NSJSONReadingAllowFragments
error: &error];
But that means the NSString you pasted in your question contains extra characters which are not following JSON format. If you add more code from where you take this value (file, web) - I can help more to make it valid. Until then treat this answer as workaround :)
The properly formatted string should be:
{\"ApplicationId\":1,\"CurrentPosition\":0,\"EndOfFile\":false,\"Media\":{\"Active\":true,\"Description\":\"This video demonstrates a quick overview of Bentley LEARN Server.\",\"LocationId\":1,\"MP4URL\":\"http:\\/\\/cdnllnw.bentley.com\\/s\\/LearnVideo\\/Welcome.mp4?s=1380034262&e=1380077462&h=c2641922fd862ffe5c5a05e94786359a\",\"MediaId\":5003235,\"MediaURL\":\"http:\\/\\/cdnllnw.bentley.com\\/s\\/LearnVideo\\/Welcome.mp4?s=1380034262&e=1380077462&h=c2641922fd862ffe5c5a05e94786359a\",\"StreamServer\":null,\"Title\":\"Welcome\",\"TransferStatus\":0,\"filesize\":9094429},\"MediaDuration\":0,\"SkippedCurrentPosition\":0,\"UserBP\":8011512,\"ViewedTime\":0}
Without " at the beggining and at the end. Maybe that's the reason.
If you are loading this from web - make sure you don't have any JS included or extra headers and confirm that your web service responds with JSON format in headers.
I've try your NSString with the next piece of code (it's a starting point) to output the dictionary from "Media";
NSString *string = #"{\"ApplicationId\":1,\"CurrentPosition\":0,\"EndOfFile\":false,\"Media\":{\"Active\":true,\"Description\":\"This video demonstrates a quick overview of Bentley LEARN Server.\",\"LocationId\":1,\"MP4URL\":\"http:\\/\\/cdnllnw.bentley.com\\/s\\/LearnVideo\\/Welcome.mp4?s=1380034262&e=1380077462&h=c2641922fd862ffe5c5a05e94786359a\",\"MediaId\":5003235,\"MediaURL\":\"http:\\/\\/cdnllnw.bentley.com\\/s\\/LearnVideo\\/Welcome.mp4?s=1380034262&e=1380077462&h=c2641922fd862ffe5c5a05e94786359a\",\"StreamServer\":null,\"Title\":\"Welcome\",\"TransferStatus\":0,\"filesize\":9094429},\"MediaDuration\":0,\"SkippedCurrentPosition\":0,\"UserBP\":8011512,\"ViewedTime\":0}";
NSString *newString = [string stringByReplacingOccurrencesOfString:#"\\" withString:#""];
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:[newString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableLeaves error:nil];
NSLog(#"%#", [dictionary valueForKey:#"Media"]);
And the result is:
{
Active = 1;
Description = "This video demonstrates a quick overview of Bentley LEARN Server.";
LocationId = 1;
MP4URL = "http://cdnllnw.bentley.com/s/LearnVideo/Welcome.mp4?s=1380034262&e=1380077462&h=c2641922fd862ffe5c5a05e94786359a";
MediaId = 5003235;
MediaURL = "http://cdnllnw.bentley.com/s/LearnVideo/Welcome.mp4?s=1380034262&e=1380077462&h=c2641922fd862ffe5c5a05e94786359a";
StreamServer = "<null>";
Title = Welcome;
TransferStatus = 0;
filesize = 9094429;
}
Hope it will be useful for you.

iOS - NSJSONSerialization: Unable to convert data to string around character

I'm getting this error while parsing JSON:
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Unable to convert data to string around character 73053.) UserInfo=0x1d5d8250 {NSDebugDescription=Unable to convert data to string around character 73053.}
Any suggestions how to fix this?
ADDED
As it says in error report, the parser can't go through the character at position 73053, which is "ø" in my JSON response. As far as I know characters like Ø,Å,Æ etc. shouldn't be a problem for json parsers?
Yes, I have the same problem with encoding issue and got the above error. I got the NSData from server as encoding:NSISOLatin1StringEncoding. So I had to convert it to UTF8 before parsing it using NSJSONSerialization.
NSError *e = nil;
NSString *iso = [[NSString alloc] initWithData:d1 encoding:NSISOLatin1StringEncoding];
NSData *dutf8 = [iso dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:dutf8 options:NSJSONReadingMutableContainers error:&e];
Switf 3
let responseStrInISOLatin = String(data: data, encoding: String.Encoding.isoLatin1)
guard let modifiedDataInUTF8Format = responseStrInISOLatin?.data(using: String.Encoding.utf8) else {
print("could not convert data to UTF-8 format")
return
}
do {
let responseJSONDict = try JSONSerialization.jsonObject(with: modifiedDataInUTF8Format)
} catch {
print(error)
}
Check that the data you're parsing is actually valid JSON (and not just 'nearly' JSON). That error is known to occur when you have a different data format that can't be parsed as JSON. See for example:
iOS 5 JSON Parsing Results in Cocoa Error 3840
Do you have a top-level container in your JSON too? An array or dictionary. Example:
{ "response" : "Success" }
Update
JSON's default encoding is UTF-8. Special/exotic characters aren't a problem for UTF-8, but please ensure that your server is returning its content properly encoded as UTF-8. Also, have you done anything to tell your JSON interpretter to use a different encoding?
If your JSON is coming from a web service, put the URL into this page to see what it has to see about the encoding:
http://validator.w3.org/
Swift 5:
Yes, i got the same error while parsing JSON data.
Solution : You have to first convert response data into String and then convert that Sting to Data using UTF8 encoding before decoding.
let utf8Data = String(decoding: responseData, as: UTF8.self).data(using: .utf8)

Resources