Check if contain Null - ios

When I print the following I get (null)
NSLog(#"%#", [[responseObject objectAtIndex:i] objectForKey:#"child"]);
Now I want to do a validation to check if it returns (null). How am I supposed to do this?
I tried the following but it doesn't work:
1.
if (![[[responseObject objectAtIndex:i] objectForKey:#"child"] isEqualToString:#"(null)"]) {
}
2.
if (![[[responseObject objectAtIndex:i] objectForKey:#"child"] isEqual:#"(null)"]) {
}

"null" isn't just a NSString. You should do some research into the concept of a null object.
What you're looking for can be written like this:
if (![[responseObject objectAtIndex:i] objectForKey:#"child"]) {
//key "child" not in dictionary
}

(null) is the representation of nil displayed by NSLog.
You can write the following:
if ([[responseObject objectAtIndex:i] objectForKey:#"child"] == nil) {
}
Or a shorter alternative:
if (![[responseObject objectAtIndex:i] objectForKey:#"child"]) {
}

Another way to check is to use string length. I know other answers are just as good, I am just giving OP and anyone else in future some more options.
NSString *childStr = [[responseObject objectAtIndex:i]objectForKey:#"child"];
if ([childStr length] < 1)
{
//no value specified - childStr is NULL
}
else
{
//there is something in the childStr - throw a party!
}

NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
if ([defaults objectForKey:#"hello"]) {
NSLog(#"only if not null show %#",[defaults objectForKey:#"hello"]);
}
This is a way to check it from User Defaults. It will only print if the saved object does not equal null.

Related

NSNull returns <null> instead of returning null

I'm using the following code to check if a NSNumber has nil value. So I'm converting the NSNumber to string and Im checking if its length is 0. If it is of zero, Im returning NSNull else Im returning the number itself.
- (id)NSNullToNilForKey:(NSNumber *)number
{
if ([[number stringValue] length] == 0){
return [NSNull null];
}
return number;
}
Im invoking it as follows,
NSString *bodyString = [NSString stringWithFormat:#"[ \"%#\",{\"session_token\": \"%#\",\"request\": [\"GetAssigneeWiseCompliancesChart\",{\"country_id\": %#,\"business_group_id\": %#,\"legal_entity_id\": %#,\"division_id\": %#,\"unit_id\": %#,\"user_id\": %#}]}]",clientSessionId,clientSessionId,[self NSNullToNilForKey:countryId],[self NSNullToNilForKey:businessGroupId],[self NSNullToNilForKey:legalEntityId],[self NSNullToNilForKey:divId],[self NSNullToNilForKey:unitId], [self NSNullToNilForKey:userId]];
But the problem is that, though the if loop is getting invoked. The value returned from the if loop of NSNullToNilForKey is <null> instead of null. How can I sort this out?
You're creating a string from a format, all of the parameters are added by taking their description, what you're seeing is the description of the NSNull instance.
Your method should specifically return a string and you should choose explicitly what string you want to return.
- (id)NSNullToNilForKey:(NSNumber *)number
{
if ([[number stringValue] length] == 0){
return #"NSNull";
}
return number;
}
try this
change the type anyobject id to NSNumber *
- (NSNumber *)NSNullToNilForKey:(NSNumber *)number
{
if ([[number stringValue] length] == 0){
return [NSNull null];
}
return number;
}

Working with multiple objects in NSArray

There's a table view that has a list of things. The user can select multiple rows in this table. I'm storing each in an array.
I then want to loop through that array to get each item in it's own string that I can set it up to a key.
Here's something I have tried:
for (NSString *str in self.myArray) {
if ([str isEqual:#"Blah"]) {
self.blahString = str;
} else {
self.blahString = #"";
}
if ([str isEqual:#"Blah Blah"]) {
self.blahblahString = str;
} else {
self.blahblahString = #"";
}
if ([str isEqual:#"Blah Blah Blah"]) {
self.blahblahblahString = str;
} else {
self.blahblahblahString = #"";
}
}
if (self.myArray.count == 0) {
[self.answersToPass setObject:#"" forKey:#"Blah"];
[self.answersToPass setObject:#"" forKey:#"Blah Blah"];
[self.answersToPass setObject:#"" forKey:#"Blah Blah Blah"];
} else {
[self.answersToPass setObject:self.blahString forKey:#"Blah"];
[self.answersToPass setObject:self.blahblahString forKey:#"Blah Blah"];
[self.answersToPass setObject:self.blahblahblahString forKey:#"Blah Blah Blah"];
}
The goal here is if the user doesn't select anything, then just set each objectForKey to an empty string, else pull out each string and match it to it's right key.
EDIT:
I believe I have solved my issue. I scratched the above code completely.
I found an 'order-of-operation' error on my end. Totally my fault. Should have looked through my code line-by-line more carefully.
If I encounter any issues with this again I'll update the post here.
I appreciate everyone's input and help. I apologize for not being thorough enough in my question.
Your question is not super lucidly worded, so I'll do my best but I'm not sure what precisely you want.
1) It sounds like you are checking all the time if the user selected something. Why? This is a terrible idea. Instead, add a responder to change stuff when the user actually does select something.
2) This manual setup is not great - what if someday you want to have 500 different items? Are you going to manually enter each if statement?
Try something more like this.
for (NSString *string in self.myArray)
{
if (self.answersToPass[string])
[self.answersToPass setObject: string forKey:string];
for (id key in self.answersToPass)
if (key isEqualToString:(string))
[self.answersToPass setObject: string forKey:key];
else [self.answersToPass setObject: "" forKey:key];
}
Please note that the above is not tested so you may have to fix some bug with my obj c notation or something but it should show the right idea.
I would note that this basic structure of a dict with strings equaling each other sounds very silly. Why store a key and value that either are equal or where the value is null and then check each time? Wouldn't it be easier to just hold an array of booleans? Or a map of strings to booleans?
You will better define a data structure (e.g. NSMutableArray or NSMutableDictionary) as a property, and store the str into it, so that you can access them at a later time.
#property (nonatomic, strong) NSMutableArray *array;
for (NSString *str in self.myArray) {
[array addObject str];
}

How to check if json object contains <null>?

I am getting a Json from server by making a network request in my app.I am getting <null> value for some keys in Json object.My app gets crashed if this type of response is received.Please tell me how can i validate>?
I have tried this but it does not work all time.
if(!(user_post.username==(id)[NSNull null]) )
{
user_post.username=[dict_user_info objectForKey:#"name"];
if(user_post.username!=nil)
{
ser_post.username=[dict_user_info objectForKey:#"name"];
}
else
{
user_post.username=#"Username";
}
}
Consider testing the value for null so your program won't crash. Like this:
if([dict_user_info objectForKey:#"name"] != [NSNull null])
{
ser_post.username=[dict_user_info objectForKey:#"name"];
}
Create a Category of NSDictionary and add following method in it, which replaces null value with empty string for each key in dictionary.
- (NSDictionary *)dictionaryByReplacingNullsWithStrings
{
const NSMutableDictionary *replaced = [self mutableCopy];
const id nul = [NSNull null];
const NSString *blank = #"";
for(NSString *key in self) {
const id object = [self objectForKey:key];
if(object == nul || object == NULL) {
//pointer comparison is way faster than -isKindOfClass:
//since [NSNull null] is a singleton, they'll all point to the same
//location in memory.
[replaced setObject:blank
forKey:key];
}
}
return [replaced copy];
}
Usage :
[yourJSONDictionary dictionaryByReplacingNullsWithStrings];
Read more about Category in iOS Tutorial 1 and Tutorial 2
yourJsonObject = [myDic valueforkey#"key"];
if(yourJsonObject != [NSNull null])
{
//not null
}
** you can also check whether object exist or not
if(yourJsonObject)
{
//exist
}
I think you've confused your logic. I am trying to stay true to your code, but let me know if the following is not what you intended:
if (dict_user_info[#"name"] != nil && [dict_user_info[#"name"] isKindOfClass:[NSNull class]] == NO) {
user_post.username = dict_user_info[#"name"];
if (user_post.username != nil) {
ser_post.username = user_post.username;
} else {
user_post.username = #"Username";
}
}
These are a couple of methods I wrote for my projects, try them :
/*!
* #brief Makes sure the object is not NSNull or NSCFNumber, if YES, converts them to NSString
* #discussion Sometimes JSON responses can contain NSNull objects, which does not play well with Obj-C. So when you access a value from a JSON and expect it to be an NSString, pass it through this method just to make sure thats the case.
* #param str The object that is supposed to be a string
* #return The object cleaned of unacceptable values
*/
+ (NSString *)cleanedJsonString:(id)str
{
NSString *formattedstr;
formattedstr = (str == [NSNull null]) ? #"" : str;
if ([str isKindOfClass:[NSNumber class]]) {
NSNumber *num = (NSNumber*) str;
formattedstr = [NSString stringWithFormat:#"%#",num];
}
return formattedstr;
}
/*!
* #brief Makes Sure the object is not NSNull
* #param obj Sometimes JSON responses can contain NSNull objects, which does not play well with Obj-C. So when you access a value from a JSON ( NSArray, NSDictionary or NSString), pass it through this method just to make sure thats the case.
* #return The object cleaned of unacceptable values
*/
+ (id)cleanedObject:(id)obj
{
return (obj == [NSNull null]) ? nil : obj;
}
/*!
* #brief A JSON cleaning function for NSArray Objects.
* #discussion Sometimes JSON responses can contain NSNull objects, which does not play well with Obj-C. So when you access a value from a JSON and expect it to be an NSArray, pass it through this method just to make sure thats the case. This method first checks if the object itself is NSNull. If not, then it traverses the array objects and cleans them too.
* #param arr The Objects thats supposed to be an NSArray
* #return The NSNull Cleaned object
*/
+ (NSArray *)cleanedJsonArray:(id)arr
{
if (arr == [NSNull null]) {
return [[NSArray alloc] init];
}
else
{
NSMutableArray *arrM = [(NSArray*)arr mutableCopy];
int i=0;
for (id __strong orb in arrM)
{
if (orb == [NSNull null])
{
[arrM removeObjectAtIndex:i];;
}
i++;
}
return arrM;
}
}
Just pass a JSON string, array or object to the appropriate method and the method will clean it for you.
Do yourself a favour and write a method that handles this and put it into an extension. Like
- (NSString*)jsonStringForKey:(NSString*)key
{
id result = self [key];
if (result == nil || result == [NSNull null]) return nil;
if ([result isKindOfClass:[NSString class]]) return result;
NSLog (#"Key %#: Expected string, got %#", key, result);
return nil;
}
You might even add some code that accepts NSNumber* results and turns them into strings, if that is what your server returns (some poster here had the problem that his server returned dress sizes as numbers like 40 or strings like "40-42" which makes something like this useful).
And then your code becomes one readable line
user_post.username = [dict_user_info jsonStringForKey:#"name"] ?: #"username";
I actually use several slightly different methods depending on whether I expect null, expect no value, expect an empty string or not, which gives me warnings when my assumptions are wrong (but always returns something that doesn't break).
try this:
if(!(user_post.username == (NSString *)[NSNull null]) )

NSNull isEqualToString: unrecognized selector on ObjC

Well my code was like this:
I have two strings, place and date. I am using them like this:
cell.datePlace.text= [NSString stringWithFormat:#"%#, %#",date,place];
In some entries, the output is like this:
"21/10/2012, <null>"
"21/11/2012, None"
"21/12/2013, London"
My app does not crash but I want the place to be visible only when is not null and not equal to None.
So I tried this:
NSString * place=[photo objectForKey:#"place"];
if ([place isEqualToString:#"None"]) {
cell.datePlace.text= [NSString stringWithFormat:#"%#",date];
} else {
cell.datePlace.text= [NSString stringWithFormat:#"%#, %#",date,place];
}
Problem was when place was <null> my app crashed and I got this error:
[NSNull isEqualToString:] unrecognized selector send to instance
So, i tried this:
if (place) {
if ([place isEqualToString:#"None"]) {
cell.datePlace.text= [NSString stringWithFormat:#"%#",date];
} else {
cell.datePlace.text= [NSString stringWithFormat:#"%#, %#",date,place];
}
} else {
cell.datePlace.text= [NSString stringWithFormat:#"%#",date];
}
But the problem remains.
I guess your source data is coming from JSON or similar (something where data is being parsed in and missing data is being set to NSNull). It's the NSNull that you need to deal with and aren't currently.
Basically:
if (place == nil || [place isEqual:[NSNull null]]) {
// handle the place not being available
} else {
// handle the place being available
}
Use
if (! [place isKindOfClass:[NSNull class]) {
...
}
instead of
if (place) {
...
}
Note: NSNull object is not nil, so the if (place) will be true then.
Use [NSNull null]:
if ([place isKindOfClass:[NSNull class]])
{
// What happen if place is null
}

Check key exists in NSDictionary

how can I check if this exists?:
[[dataArray objectAtIndex:indexPathSet.row] valueForKey:#"SetEntries"]
I want to know whether this key exists or not. How can I do that?
Thank you very much :)
EDIT:
dataArray has Objects in it. And these objects are NSDictionaries.
I presume that [dataArray objectAtIndex:indexPathSet.row] is returning an NSDictionary, in which case you can simply check the result of valueForKey against nil.
For example:
if ([[dataArray objectAtIndex:indexPathSet.row] valueForKey:#"SetEntries"] != nil) {
// The key existed...
}
else {
// No joy...
}
So I know you already selected an answer, but I found this to be rather useful as a category on NSDictionary. You start getting into efficiency at this point with all these different answers. Meh...6 of 1...
- (BOOL)containsKey: (NSString *)key {
BOOL retVal = 0;
NSArray *allKeys = [self allKeys];
retVal = [allKeys containsObject:key];
return retVal;
}
Check if it's nil:
if ([[dataArray objectAtIndex:indexPathSet.row] valueForKey:#"SetEntries"] != nil) {
// SetEntries exists in this dict
} else {
// No SetEntries in this dict
}
this also works using Objective-C literals using the following syntax:
NSDictionary *dict = #{ #"key1" : #"value1", #"key2" : #"value2" };
if (dict[#"key2"])
NSLog(#"Exists");
else
NSLog(#"Does not exist");
Try this:
if ([dict objectForKey:#"bla"]) {
// use obj
} else {
// Do something else like create the object
}
This one does the same but with less code:
if (dataArray[indexPathSet.row][#"SetEntries"] != nil) { /* the key exists */ }
else { /* the key doesn't exist */ }
if ((NSNull *)[[dataArray objectAtIndex:indexPathSet.row] valueForKey:#"SetEntries"] != nil) {
// SetEntries exists in this dict
} else {
// No SetEntries in this dict
}
That's the right answer.
Check dictionary contains any value. I prefer [dic allKeys].count > 0 to check.
Use the (unsigned long) option:
if ( (unsigned long)[[dataArray objectAtIndex:indexPathSet.row] valueForKey:#"SetEntries"] ) {
// Key exist;
}else{
// Key not exist;
};

Resources