I have talbeView that populate data from JSON. One my text label fill itself with NSString, and sometimes it output 0(NSNULL), which obviously, not suppose to be output on cell text label.
Following code:
if ([(cell.myNameLabel.text) isEqual: #"0(NSNull)"]){
cell.myNameLabel.text = #"No Name";
}
Isn't work, i wonder why?
How to fix that?
Data populated from JSON use here like this :
//use accordingly that it may contain either NSDictionary or NSArray.
NString *strValue = youJSONDataArray[indexPath.row];
if ([value isEqual:[NSNull null]] || value.length == 0) {
strValue == #"";
}
Set string value in UILabel like this:
cell.myNameLabel.text = strValue;
NSJSONSerialization uses NSNull to indicate a null JSON value.
Try this instead:
if ([cell.myNameLabel.text isEqual:[NSNull null]]) {
// …
}
But you'll probably want to strip out the NSNulls during parsing so that your code isn't littered with NSNull checks.
If a JSON response has a null value then its indicated by NSNull by NSJSONSerialization class so you can modify your code to
if ([cell.myNameLabel.text isEqual:[NSNull null]]) {
// your logic here
}
Related
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]) )
This is my NSArray :
(
"tag_name",
3,
"mp4_url",
4,
0,
"back_tag",
5,
1,
"part_id",
"related_list",
2
)
I need to put all the numerical values in some another array.
I used the following code to check whether the value fetched from the array was a numeric or a string, but it didn't work. Every time i get the value from an array as NSString.
for (int i=0; i<arr.count; i++) {
id obj=[arr objectAtIndex:i];
if ([obj isKindOfClass:[NSString class]])
{
// It's an NSString, do something with it...
NSLog(#"its string");
}else{
// It's an Numerical value, do something with it...
NSLog(#"its integer value");
}
}
I know that array stores only kind of objects in it, so while fetching i'm getting the value as NSString(i.e object). But is there anyway to check whether the value stored was a numeric value.
Please can anyone help me..
Thanks
You can't just turn an NSString into an NSNumber but there are ways that you can try to get he numeric value out of them.
This is one option but you could also have a look at NSNumberFormatter.
If all of the numbers are integers then you could do something like this...
// always use fast enumeration
for (NSString *string in arr) {
NSInteger integer = [string integerValue];
// have to check explicitly for 0 as a non-numeric would return 0 above
if ([string isEqualToString:#"0"]
|| integer != 0) {
// it is an integer numeric string
} else {
// it is a string
}
}
I'm try to set an NSDictionary to a JSON object retrieved from the server, I'm doing that in this line:
_peopleArray = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
It works fine and properly creates the dictionary. However, I have a problem, values that are null in the JSON object are stored as "<null>" string values in the dictionary. Is there any way to fix this or work around it? I want to avoid traversing through the entire thing and setting them to #"".
Thanks for any help!
~Carpetfizz
You are wrong. null values in JSON are not stored as <null> string values. They are stored as NSNull objects, which NSLog logs as <null>.
You can never trust what data you were given. If you assume you got an NSString and the server sends you a number, your code is likely to crash.
NSString* myJSONString = ...;
if ([myJSONString isKindOfClass:[NSString class]]) {
it is a string
} else {
it is not a string
}
There is nothing I guess, though it can be easily corrected from api makers, if not possible, you can always put a simple macro, I use to avoid such thing, follow macro below
#define Is_Empty(value) (value == (id)[NSNull null] || value == nil || ([value isKindOfClass:[NSString class]] && ([value isEqualToString:#""] || [value isEqualToString:#"<null>"]))) ? YES : NO
#define IfNULL(original, replacement) IsNULL(original) ? replacement : original
#define IsNULL(original) original == (id)[NSNull null]
#define SafeString(value) IfNULL(value, #"")
Usage
self.label.text=SafeString([dic objectForKey:#"name"]);
I am loading data from a server but I have an issue that the value that I am returning is zero(0) while I can't go inside if. Please where would be the problem?
-(void)method1
{
NSNumber *value = [data objectForKey:#"samount"];
NSLog(#"number is -%#-", value); //number is -0-
if (value == 0)
{
NSLog(#" OK :) ");
}
else
{
NSLog(#" Bad :( ");
}
}
Use isEqual:
if ([value isEqual:#(0)])
That will also evaluate correctly in case value is nil (where == comparison with floatValue or similar methods would fail)
value is an object, and more precisely a NSString object (as per your comments in Alladinian's answer), but you are checking its address. You can convert your string to NSNumber with NSNumberFormatter and then check its value or rely on NSString's built-in methods: integerValue, floatValue, etc.
Assuming value is a NSNumber/NSString:
if ([value integerValue] == 0)
See Getting Numeric Values in NSString documentation and Accessing Numeric Values in the NSNumber documentation and pick the method that best suits your data type.
My if statement won't work. active returns 1 but will not work in the IF statement
JSONDecoder *jsonKitDecoder = [JSONDecoder decoder];
NSDictionary *dict = [jsonKitDecoder objectWithData:jsonData];
NSString *userid = [dict valueForKeyPath:#"users.user_id"];
NSString *active = [dict valueForKeyPath:#"users.active"];
NSLog(#"%#",userid); // 2013-06-20 03:03:21.864 test[81783:c07] (74)
NSLog(#"%#",active); // 2013-06-20 03:03:21.864 test[81783:c07] (1)
if ([active isEqualToString:#"1"]){
// Do something
}
I can't seem to get this IF to work. Do I need to change the NSString to a int?
For starters, use a modern style for retrieving values from dictionaries, rather than valueForKeyPath:.
NSDictionary* users = dict[#"users"];
id active = users[#"active"];
Once you're using a modern style, my guess is that the active value is actually an NSNumber representing a boolean value. So your if block would read:
if([active isKindOfClass:NSNumber] && [active boolValue]) {
//active is an NSNumber, and the user is active
}
The syntax of your if statement is just fine. I would try the alternate method for retrieving values from a dictionary as mentioned above.
NSString *active = #"1";
if ([active isEqualToString:#"1"])
{
// Do something
NSLog(#"It works!");
}
More than likely the "users.active" object being returned from that NSDictionary-ized JSON stream is a "BOOL" or a "NSInteger" as the payload of a NSNumber object and it's not a NSString object.
Try using:
NSNumber * activeNumber = [dict valueForKeyPath: #"users.active"];
and see if "if ([activeNumber boolValue] == YES)" works better for you.