Objective-C: How to put boolean values in JSON dictionary? - objective-c

I could not find out how to insert a boolean value (to appear as key:true in the JSON string) in my NSDictionary:
NSMutableDictionary* jsonDict = [NSMutableDictionary dictionary];
[jsonDict setValue: YES forKey: #"key"];
The code above does not run (obviously because YES is not an object).
How can I accomplish this?

You insert booleans into a dictionary using NSNumber. In this case, you can use the literal expression #YES directly, together with a dictionary literal, to make this a one-liner:
NSDictionary *jsonDict = #{#"key" : #YES};
To encode it to JSON, use +[NSJSONSerialization dataWithJSONObject:options:error]:
NSError *serializationError;
NSData *jsonData = [NSJSONSerialization
dataWithJSONObject:jsonDict
options:0 error:&serializationError];
if (!jsonData) {
NSLog(#"%s: error serializing to JSON: object %# - error %#",
__func__, jsonDict, serializationError];
}

+[NSNumber numberWithBool:] is the typical way to add a boolean to a NSDictionary.

With Objective-C literals, [NSNumber numberWithBool:YES] can be represented with just #YES,
You can create your dictionary like so:
NSDictionary *jsonDict = #{#"key":#YES};

Related

How to detect if the NSDictionary item is an integer?

I have a NSDictionary object with 2 items, the first one is a NSString and the second is an Integer. When I loop into the dictionary items I'd like detect what of they is an Integer.
What is the best way to do it?
The current dictionary is:
[[NSDictionary alloc] initWithObjectsAndKeys:#"San", #"name", #"123", #"id", nil]
The item you are putting in the dictionary is in no way an integer, it's a NSString which only contains numbers. Why not just use a NSNumber object and use it the way it should be?
[[NSDictionary alloc] initWithObjectsAndKeys:#"San", #"name", #123, #"id", nil]
This uses a literal for a NSNumber.
You can use isKindOfClass: to check if an object is of a specific class and enumerateKeysAndObjectsUsingBlock: to analyze every object contained in a dictionary.
For example:
NSDictionary *dictionary = #{#"name": #"San", #"id": #123};
[dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if ([obj isKindOfClass:[NSNumber class]])
NSLog(#"%#: %# is a number", key, obj);
else
NSLog(#"%#: %# is NOT a number", key, obj);
}];
The first line is a NSDictionary creation using literals, the same is for #123, which automatically insert a NSNumber with 123 value in the dictionary.

How to convert NSString object into Array in Objective-C?

I have below string:
{"list": {"array":[{"current_rate":20.0,"id":1, "name": "abc"},
{"current_rate":20.0,"id":2, "name": "xyz"}]}}
I want to convert above string into array like
[current_rate: 20.0, id: 1, name: abc]
I used componentSeperatedByString:#":".
But it gives problem when name field contain ":" string.
Is there any way to convert above string into array.
The string you have seems valid JSON. You may want to parse it:
NSData *data = [theString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
Then you can get the object using the objectForKey: and objectAtIndex: methods on the appropriate classes.

Why can I pull one string out of an NSDictionary, but not another?

I have an NSDictionary and I am trying to pull a string out of it. For some reason, the last string seems irretrievable(!?!). In the code below, I retrieve the NSString object for labelString, with no problem at all. But when I try to retrieve the NSString for foo, I always get nil. But I don't see the difference - can you see what I'm doing wrong?
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:CellStyleLabelledStringCell], #"cellStyle",
#"name", #"fieldName",
#"Name", #"labelString",
foodItem.name, #"contentString",
#"foo", #"fookey",
nil];
NSString *string1 = (NSString *)[dict objectForKey:#"fookey"];
NSString *string2 = (NSString *)[dict objectForKey:#"labelString"];
NSLog(#"[%#][%#]", string1, string2);
The log message looks like this, and backs-up what I'm seeing in the debugger (i.e., string1 is null):
2012-03-17 21:35:03.302 QuickList7[8244:fb03] [(null)][Name]
Truly perplexed. Thanks in advance.
foodItem.name is nil, so -[NSDictionary dictionaryWithObjectsAndKeys:] stops there, and doesn't add the subsequent objects to the dictionary.
In other words, it's as if you did this:
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:CellStyleLabelledStringCell], #"cellStyle",
#"name", #"fieldName",
#"Name", #"labelString",
nil];
This is why you have to be careful with any method that takes nil as an "end of arguments" sentinel.
Kurt's answer is correct, foodItem.name is nil.
To prevent that, you can either always check objects to see if they're nil before adding to a dictionary, or use the following macro to replace all nil items with NSNull objects:
#define n2N(value) (value ? value : [NSNull null])
So using that macro, your code above would look like:
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:CellStyleLabelledStringCell], #"cellStyle",
#"name", #"fieldName",
#"Name", #"labelString",
n2N(foodItem.name), #"contentString",
#"foo", #"fookey",
nil];
Also, there's no need to typecast the result of objectForKey: to NSString since that method returns id.

How to convert a JSON array into an NSArray

I've been having trouble finding out how to convert a JSON array into an NSArray.
I have a php script that creates an array that is converted into JSON which is then sent and stored into an NSString that looks like:
[1,2,3,4]
My problem is that I need to make that into an NSArray of ints. How would one do that?
Thanks!
You should look at the documentation of the NSJSONSerialization class.
You can hand it the NSData received from a remote call that is a string in JSON format and receive the array or dictionary it contains.
NSObject *o =[NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
// other useful "options":
// 0
// NSJSONReadingMutableLeaves
// NSJSONReadingMutableLeaves | NSJSONReadingMutableContainers
you should then check that o is of the type you expect for sanity purposes
If I wanted to quickly break that into an array I would do it like this:
NSString * jstring = #"[1,2,3,4]"; //your json string
jstring = [jstring stringByReplacingOccurrencesOfString:#"[" withString:#""];
jstring = [jstring stringByReplacingOccurrencesOfString:#"]" withString:#""];
NSArray * intArray = [string componentsSeparatedByString:#","];
//you could create your int from the array like this
int x = [[intArray objectAtIndex:0]intValue];
Import the SBJson in your project (drag and drop it)
#import "SBJson.h"
Then where you receive the JSON response from the php file
NSArray *array = [responseString JSONValue];

I am typing in text from a book for NSDictionary and get an error from it?

I typed in text from a book and
I get this error: Passing argument of 1 of "initWithObjects:forKeys:count:" from incompatible pointer type
NSDictionary *dict = [[NSDictionary alloc] initWithObjects: #"hello", #"there", #"persn"
forKeys: #"aa", #"bb", #"cc"
count: 3 ];
NSLog(#"%#", [dict objectForKey: #"bb"]);
In Objective-C, methods can't use var-args like that, they must always come at the end of the invocation.
In fact, the parameters to your message invocation are actually pointers to buffers of objects and keys.
Try this:
id objects[] = {#"hello", #"there", #"person"};
id keys[] = {#"aa", #"bb", #"cc"};
NSDictionary *dict1 = [[NSDictionary alloc] initWithObjects:objects forKeys:keys count:3];
NSLog(#"%#", [dict1 objectForKey: #"bb"]);