How to check NSDictionary values are nil in iPhone - ios

I have one NSDictionary and in that dictionary keys and values are dynamically added.Now I want to check if any value is nil then set empty string for that key.How can I check this? Now I am checking this using conditions but, Is there any simple way to check nil or empty values.Please help me,Thanks

NSDictionary does not hold nil values for its keys.
If you want to test the presence/absence of a specific key's value, you can use -objectForKey:. The method returns nil if the key/value pair is absent.
For "empty values", you will have to expand on what is considered an empty value in the context of your program (e.g. some people use NSNull to indicate an empty value, or if you are working with strings as values an empty string).

For any key you haven’t set a value for, your dictionary will return nil from -objectForKey:—in other words, if nothing’s set for a given key, that key doesn’t exist in the dictionary.
That said, it sounds like you have a list of keys that you’d like to ensure have a placeholder value in the dictionary, with that placeholder value being an empty string. For that, you’d want to do something like this:
- (void)addPlaceholdersForKeys:(NSArray *)keys toDictionary:(NSMutableDictionary *)dictionary {
for (id key in keys) {
if ([dictionary objectForKey:key] == nil) {
[dictionary setObject:#"" forKey:key];
}
}
}

NSDictionary and other collections cannot contain nil values. But it must store a null value. You can check it like that:-
if (dictionary[key] == [NSNull null]) {
[dictionary setObject:#"" forKey:key];
}
For more refer sample code:-
NSMutableDictionary *dict=[NSMutableDictionary dictionary];
[dict setObject:#"test" forKey:#"key1"];
[dict setObject:#"test1" forKey:#"key2"];
[dict setObject:[NSNull null] forKey:#"key3"];
NSLog(#"%#",dict);
if (dict[#"key3"]==[NSNull null])
{
[dict setObject:#"" forKey:#"key3"];
NSLog(#"%#",dict);
}
Output:-
Before setting empty value:-
{
key1 = test;
key2 = test1;
key3 = "<null>";
}
After setting empty value:-
{
key1 = test;
key2 = test1;
key3 = "";
}

you can do like this by looping through the dictionary
NSArray *keys = [dictionary allKeys];
for(NSString *key in keys)
{
if ([dictionary objectForKey:key] == NULL)
{
[dictionary setObject:#"" forKey:key];
}
}

Related

Get A Certain Value In NSDictionary

Let's say the name of dictionary is nameOfDictionary and the key name is string.
I was trying to get the value of the dictionary by using:
[nameOfDictionary objectForKey:#"string"];
However, I was getting the one at the bottom. Is there anyway I can get the 222 or sample alone?
{
222 = "sample";
}
It appears that the object under the "string" key is also a dictionary. So you can do this to get the key and value of that dictionary separately.
NSDictionary *nameOfDictionary = #{#"string":#{#"222":#"Sample"}};
NSDictionary *dict = nameOfDictionary[#"string"];
for (NSString *key in [dict keyEnumerator]) {
NSLog(#"%# = %#", key, dict[key]);
}
key will contain 222 and dict[key] will contain sample
Try allKeys function will return all keys,
for( NSString *aKey in [dictionary allKeys])
{
NSLog(#"Do something with the key here:%#",aKey );
}

How to tell the difference between a Boolean and an NSNumber in CoreData

I have some parsing code I'm using for serialising and deserialising objects from our web service and I've hit a bit of a problem when serialising booleans.
The serialisation looks like this:
- (NSDictionary *)dictionaryRepresentationWithMapping:(NSDictionary *)mappingDictionary
{
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc]init];
for (id key in[mappingDictionary allKeys])
{
id value = [self valueForKey:key];
if ((value != [NSNull null]) && (![value isKindOfClass:[NSNull class]]) && (value != nil))
{
[dictionary setObject:value forKey:mappingDictionary[key]];
}
}
return [NSDictionary dictionaryWithDictionary:dictionary];
}
The problem is that when I call valueForKey: on my NSManagedObject and then add this to my dictionary I end up with the value being set as if I was calling:
[dictionary setObject:#1 forKey:mappingDictionary[key]];
instead of:
[dictionary setObject:#YES forKey:mappingDictionary[key]];
This means that when I turn this into JSON, in the next stage, I'm sending 1 instead of true to the server.
So what I need is a way of retaining the fact that this is an NSNumber representing a bool as opposed to a number. I've tried asking for the class but I just get back NSNumber. Is there a way I can retain this automatically or failing that, is there a way I can consult the model to see what the attribute type was set to?
Each entity has its metadata stored in NSEntityDescription and NSAttributeDescription. You can access them from NSManagedObject in a following way:
//you can put this inside the for loop
NSAttributeDescription *attributeDescription = self.entity.attributesByName[key];
if(attributeDescription.attributeType == NSBooleanAttributeType) {
//it is a boolean attribute
}
When sending a call to the server, you could do like this:
[dict setValue:[NSNumber numberWithBool:YES] forKey:mappingDictionary[key]]; ;
Or another way, you can model server side to retain its value as Boolean, and at that time, just need to send like this [dict setValue:YES] forKey:mappingDictionary[key]];
Hope it could help

Storing Multiple Values to a Single Key in NSDictionary

In my application i am getting data from the server.i parsed the data and added to individual arrays. Here i am having 2 arrays.
For example
Array A : #"1",#"2",#"3",#"2",#"3",#"4",etc..
Array B : #"A",#"B",#"C",#"D",#"E",#"F",etc..
Now i want to create a Dictionary with Array A as keys and Array B as Values.
i am trying to create Dictionary like this:
dataDict = [NSDictionary dictionaryWithObjects:B forKeys:A];
But it is giving only single value for a single Key. here how can i store multiple values for a single key.
For Different keys its working. But my problem is Storing multiple values for single key.
You can't store multiple values for a single key directly -- dictionaries can only have one value per key. What you can do is store an array as the value. So, you could create a mutable dictionary and add the keys and values one at a time. Make the values all mutable arrays, and check for an existing value for the given key before setting it. If you find one, add the new value to the array.
Try this,
Assuming dataDict is a NSMutableDictionary and initialised.
- (void)addValueInDataDict:(id)value forKey:(NSString *)key {
if ([dataDict objectForKey:key] != nil) {
//Already exist a value for the key
id object = [dataDict objectForKey:key];
NSMutableArray *objectArray;
if ([object isKindOfClass:[NSMutableArray class]]) {
objectArray = (NSMutableArray *)object;
} else {
NSMutableArray *objectArray = [[NSMutableArray alloc] init];
}
[objectArray addObject:value];
[dataDict setObject:objectArray forKey:key];
} else {
//No value for the key
[dataDict setObject:value forKey:key];
}
}

Getting values from userdefaults and creating an NSMutableDictionary

I am trying to create a dictionary which is a replica for NSUserdefaults. I want the dictionary to contain same values and keys.
But, we need to convert bool and int values to NSNumber when we save it to dictionary. Right now i am doing the following. But not sure which value is bool value and int value. If I can get to know the type of the value I can do rest. Is there any way to check the value whether it is bool or int.
NSArray *availableUserDefaultsKeys = [NSArray arrayWithObjects:#"Key1", #"Key2",nil];
NSMutableDictionary *userDefaultsDictionary = [NSMutableDictionary dictionary];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
for (NSString *key in availableUserDefaultsKeys) {
id value = [userDefaults objectForKey:key];
if (value != nil) { // Is there any way to check whether the value is bool or int here
[userDefaultsDictionary setObject:value forKey:key];
} else {
[userDefaultsDictionary setObject:[NSNull null] forKey:key];
}
}
I have checked the debug.plist which has all the user defaults stored, In that we have type field where it specifies the type. Can we get the type from this field.
You can use this way:
// v is NSNumber
if ((strcmp([v objCType], #encode(BOOL) == 0) {
// this is BOOL
}
And there are #encode(int) #encode(float)
You should avoid directly saving seperated data to NSUserDefaults, you can pack them in an object, and this object should conform NSCoding protocol. Then after you read the data out, you will know the exact type.

How to loop NSDictionary obtained from JSON?

How can i loop through the following dictionary obtained from JSON? How can i loop to get only the id 0001, 0002?
{
0001 = {
userName = "a";
photo = "";
};
0002 = {
userName = "b";
photo = "";
};
}
You loop thru the NSDictionary keys:
NSArray *keys = [dictionary allKey];
for (id *key in keys ) {
NSDictionary *userPhoto = [dictionary objectForKey:key];
// here you can either parse the object to a custom class
// or just add it to an array.
}
Or use the fast enumeration directly on the NSDictionary:
for (id *key in dictionary ) {
NSDictionary *userPhoto = [dictionary objectForKey:key];
// here you can either parse the object to a custom class
// or just add it to an array.
}
Per key you can retrieve the object.
or use the enumerateKeysAndObjectsUsingBlock:
[dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
// Here you can access the object and key directly.
}
Try this way...
Get all keys
NSArray *a=[yourDictionary allKeys];
NSArray *keys = [dictionary allKeys];
Try this. You will get all keys in an array. And then you can get them in NSString accordingly .
Another alternative is using the enumerateKeysAndObjectsUsingBlock: api to enumerate the keys and objects,
Usage is pretty simple,
[dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSLog(#"Key: %#, Value:%#",key,obj);
if([key isEqualToString:#"0001"]) {
//Do something
}
// etc.
}];
Hope that helps!
I found the answer. I already tried with the following code but it is giving all the data.
Because the json i got is in the worng format.
for (NSString *key in Dict) {}

Resources