Incorrect result from NSJSON Serialization - objective-c

I have got a very strange issue when I trying to deserialize my json string, the code is this:
NSString *testString = #"{\"cash\": 99946.222300000000}";
// NSString *testString = #"{\"cash\": \"99946.222300000000\"}"; //It's correct if I use this one
NSData *jsonData = [testString dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:nil];
NSLog(#"Convertion result is %#",error?#"false":#"true");
NSLog(#"Result data is\n %#",jsonObject);
And the result is :
2017-08-30 18:04:36.430 DAE[45557:2989692] Conversion result is true
2017-08-30 18:04:36.430 DAE[45557:2989692] Result data is
{
cash = "99946.22229999999";
}
So can anybody tell me if I did anything wrong? and how to solve it?
Really appreciate for any help.

First of all, it’s not wrong, it’s correct.
So, why you got the incorrect result?
First, The json value will be converted to a NSNumber object by NSJSONSerialization;
Then, the -description method of NSDictionary generate the result by stringValue method.
You should resolve the json value by this way to get the correct string:
[NSString stringWithFormat:%lf, [jValue doubleValue]]
But you should pay attention to the length of the value, the max length of double is 16, so if you get a number over than it, you will never get the correct result.
Tell your backend guy that they should convert all the numbers to string before they give them out, because it’s really hard to resolve them correctly if it’s big enough.

use it as Your commented string
NSString *testString = #"{\"cash\": \"99946.222300000000\"}";
NSData *jsonData = [testString dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingAllowFragments error:nil];
NSLog(#"Convertion result is %#",error?#"false":#"true");
NSLog(#"Result data is\n %#",jsonObject);

Related

NSJSONSerialization does not produce valid UTF8 string

I have an NSDictionary that I try to convert to JSON using the following code
NSData *data = [NSJSONSerialization dataWithJSONObject:dictionary options:kNilOptions error:nil];
NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
The resulting data object looks good, but the final NSString remains NULL. If I create the NSString with NSASCIIStringEncoding I get a proper string object, but any multibyte UTF8 characters are of course maimed.
Shouldn't dataWithJSONObject always yield valid UTF8 data whenever the function is succesful?
Details: I'm pretty sure the culprit is somewhere in my input data (strings parsed from custom binary format), but there is quite a lot of data and I'm not sure how to efficiently detect where the problem is.

JSON Parsing, Objective c

callback({"success":"TRUE","total_records":1,"data":[{"status_value":"1","status_text":"Login Successful","user_id":"5","u_name":"Tushar Verma"}]})
I have a service which gives the above result, so how can i get the data value using json parsing in objective c.
Thanks for the help in advance.
The NSJSONSerialization is available to iOS from 5.0 onwards.
It provides convenient methods to convert the data representation of JSON response from a server to the appropriate NSArray or NSDictionary methods.
It's harder to give a more detailed answer as you've asked such a general question.
use this simple code :-
NSString *str = #"{\"success\":\"TRUE\",\"total_records\":1,\"data\":[{\"status_value\":\"1\",\"status_text\":\"Login Successful\",\"user_id\":\"5\",\"u_name\":\"Tushar Verma\"}]}";
NSData *data = [str dataUsingEncoding:NSASCIIStringEncoding];
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
NSArray *arr =[dic objectForKey:#"data"];
NSLog(#"%#", arr);

Regex help in objective c

<NSSimpleRegularExpressionCheckingResult: 0x100217890>{0, 4}{<NSRegularExpression: 0x100214700> test 0x1}
This is one element in the array which stores the result of a regular expression search.
I've got what I want: 'test'. I don't however want all the stuff around it ie
<NSSimpleRegularExpressionCheckingResult: 0x100217890>{0, 4}{<NSRegularExpression: 0x100214700> etc
I've got a feeling I'm going to have to send something to this element ie
[element stringValue];
but I need a little help discovering what that is..
My full code is below:
NSString *test = #"test 123 test";
NSRegularExpression* regex = [[NSRegularExpression alloc] initWithPattern:#"test" options:NSRegularExpressionCaseInsensitive error:nil];
NSArray* result = [regex matchesInString:test options:0 range:NSMakeRange(0, [test length])];
NSLog(#" %#", [result objectAtIndex:0]);
which puts out
<NSSimpleRegularExpressionCheckingResult: 0x105b17890>{0, 4}{<NSRegularExpression: 0x105b14700> test 0x1}
Thanks!!
[regex matchesInString...
gives you NSArray of NSTextCheckingResults.
Maybe you'd want to use firstMatchInSting:options:range:
It will give you NSTextCheckingResult, from which you can get range (NSRange) which you apply to your string with substringWithRange: method.
I hope you can understand. If not - I'll explain more carefully.
Nevertheless, read NSRegularExpression reference and NSTextCheckingResult reference
Okay. I'm making process. If I send 'regularExpression' to the element, it narrow the result down to
<NSRegularExpression: 0x106214700> test 0x1
I'm aware that this is the print-out of an object but I am still unsure how to isolate the text!

Best way to parse a JSONP response

I am calling an API, which should return a JSON file. Here is the API link: http://sg.media-imdb.com/suggests/h/hello.json
The problem is: this JSON file has something wrapping the JSON response
imdb$hello(JSON)
So the best approch that I can see is to use a regex expression to extract only what I need. Something like: ~/\((.*)\)/.
However I would like to use the new JSON iOS5 API, which (as far as i know) only accepts NSData as input. So, I don't want to convert my response from NSData to NSString, parse that using regex, and put that in another NSData object.
Can anyone see a better/cleaner solution for that JSON parsing?
What you have isn't JSON, but JSONP. If you're not in JavaScript, I believe the correct way to handle is just as you say, preprocess and then parse.
NSError *jsonError = nil;
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSRange range = [jsonString rangeOfString:#"("];
range.location++;
range.length = [jsonString length] - range.location - 1;
jsonString = [jsonString substringWithRange:range ];
NSJSONSerialization *jsonResponse =
[NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding]
options:0
error:&jsonError];
Why don't you just do something like this before parsing the JSON?
response = [response stringByReplacingOccurrencesOfString:#"imdb$hello" withString:#""];
How regular is this string. It will always be there?
// Remove #"imdb$hello(" and #")" that wraps the response string.
NSRange JSONRange = NSMakeRange(11, [responseString length] - 12);
NSString *JSONString = [responseString substringWithRange:JSONRange];
// Now you can parse as normal…
You will need to craft the method of peeling away the wrapper with your own level of certainty.

NSData to NSString after CC_SHA1

Based on this question I wrote a category on NSString to hash NSString instances using SHA1. However, there is something wrong with my implementation. The funny thing is that logging the NSData instance does give the expected hash, but when I want to create an NSString from that NSData instance, I simply get null.
- (NSString *)sha1 {
NSData *dataFromString = [self dataUsingEncoding:NSUTF8StringEncoding];
unsigned char hashed[CC_SHA1_DIGEST_LENGTH];
if ( CC_SHA1([dataFromString bytes], [dataFromString length], hashed) ) {
NSData *dataFromDigest = [NSData dataWithBytes:hashed length:CC_SHA1_DIGEST_LENGTH];
NSString *result = [[NSString alloc] initWithBytes:[dataFromDigest bytes] length:[dataFromDigest length] encoding:NSUTF8StringEncoding];
return result;
} else {
return nil;
}
}
Thanks for the help!
The output of a hash function is just a bare bunch of bytes. You're taking those bytes, and essentially telling NSString that they represent a UTF8-encoded string, which they don't. The resulting NSString is just garbage.
It sounds like what you really want is something like a string of hexadecimal digits that represent the hash value? If so, I believe you'll need to roll this yourself by looping through the dataFromDigest one byte at a time and outputting into a new NSMutableString the right hex digits depending on the byte's value. You can do it yourself or use some code from the web. The comment on this post looks promising.