关于ios:检查Objective-C中从JSON字符串返回的空值

Checking a null value in Objective-C that has been returned from a JSON string

我有一个来自网络服务器的JSON对象。

日志是这样的:

1
2
3
4
5
6
7
8
9
10
{          
  "status":"success",
  "UserID":15,
  "Name":"John",
  "DisplayName":"John",
  "Surname":"Smith",
  "Email":"email",
  "Telephone":null,
  "FullAccount":"true"
}

请注意,如果用户未输入电话,则电话为空。

当将此值分配给NSString时,在NSLog中它以形式出现

我正在分配这样的字符串:

1
NSString *tel = [jsonDictionary valueForKey:@"Telephone"];

检查此值的正确方法是什么? 这使我无法保存NSDictionary

我尝试使用条件[myString length]myString == nilmyString == NULL

另外,在iOS文档中哪里最适合阅读此书?


是NSNull单例记录的方式。所以:

1
2
3
if (tel == (id)[NSNull null]) {
    // tel is null
}

(存在单例是因为您不能将nil添加到集合类。)


这是演员表的示例:

1
2
3
4
if (tel == (NSString *)[NSNull null])
{
   // do logic here
}


您也可以像这样检查此传入字符串:-

1
2
3
4
5
6
7
8
9
10
if(tel==(id) [NSNull null] || [tel length]==0 || [tel isEqualToString:@""])
{
    NSlog(@"Print check log");
}
else
{  

    NSlog(@Printcheck log %@",tel);  

}


如果要处理"不稳定"的API,则可能要遍历所有键以检查是否为空。我创建了一个类别来处理此问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@interface NSDictionary (Safe)
-(NSDictionary *)removeNullValues;
@end

@implementation NSDictionary (Safe)

-(NSDictionary *)removeNullValues
{
    NSMutableDictionary *mutDictionary = [self mutableCopy];
    NSMutableArray *keysToDelete = [NSMutableArray array];
    [mutDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        if (obj == [NSNull null])
        {
            [keysToDelete addObject:key];
        }
    }];
    [mutDictinary removeObjectsForKeys:keysToDelete];
    return [mutDictinary copy];
}
@end

最好的答案是亚伦·海曼(Aaron Hayman)在接受的答案下方发表的评论:

1
if ([tel isKindOfClass:[NSNull class]])

它不会产生警告:)


如果json中有许多属性,则使用if语句逐个检查它们是很麻烦的。更糟糕的是,代码将很难看且难以维护。

我认为更好的方法是创建NSDictionary类别:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// NSDictionary+AwesomeDictionary.h

#import <Foundation/Foundation.h>

@interface NSDictionary (AwesomeDictionary)
- (id)validatedValueForKey:(NSString *)key;
@end

// NSDictionary+AwesomeDictionary.m

#import"NSDictionary+AwesomeDictionary.h"

@implementation NSDictionary (AwesomeDictionary)
- (id)validatedValueForKey:(NSString *)key {
    id value = [self valueForKey:key];
    if (value == [NSNull null]) {
        value = nil;
    }
    return value;
}
@end

导入此类别后,您可以:

1
[json validatedValueForKey:key];

在Swift中,您可以执行以下操作:

1
2
3
4
let value: AnyObject? = xyz.objectForKey("xyz")    
if value as NSObject == NSNull() {
    // value is null
    }


我通常这样做:

假设我有一个用于用户的数据模型,它具有一个从JSON字典获取的NSString属性,称为email。如果在应用程序内部使用了电子邮件字段,则将其转换为空字符串可以防止崩溃:

1
2
3
4
5
6
7
- (id)initWithJSONDictionary:(NSDictionary *)dictionary{

    //Initializer, other properties etc...

    id usersmail = [[dictionary objectForKey:@"email"] copy];
    _email = ( usersmail && usersmail != (id)[NSNull null] )? [usersmail copy] : [[NSString      alloc]initWithString:@""];
}

如果我们得到的是空值,则可以使用下面的代码片段进行检查。

1
2
3
4
 if(![[dictTripData objectForKey:@"mob_no"] isKindOfClass:[NSNull class]])
      strPsngrMobileNo = [dictTripData objectForKey:@"mobile_number"];
  else
           strPsngrMobileNo = @"";

我用这个:

1
#define NULL_TO_NIL(obj) ({ __typeof__ (obj) __obj = (obj); __obj == [NSNull null] ? nil : obj; })

1
2
3
4
if([tel isEqual:[NSNull null]])
{
   //do something when value is null
}


我尝试了很多方法,但是没有任何效果。
终于这对我有用。

1
2
3
4
5
6
NSString *usernameValue = [NSString stringWithFormat:@"%@",[[NSUserDefaults standardUserDefaults] valueForKey:@"usernameKey"]];

if ([usernameValue isEqual:@"(null)"])
{
     // str is null
}

尝试这个:

1
2
3
4
if (tel == (NSString *)[NSNull null] || tel.length==0)
{
    // do logic here
}

最好的办法是坚持最佳做法-即使用真实的数据模型读取JSON数据。

看一下JSONModel-它很容易使用,它将自动为您将[NSNUll null]转换为* nil *值,因此您可以像在Obj-c中一样照常进行检查:

1
2
3
if (mymodel.Telephone==nil) {
  //telephone number was not provided, do something here
}

看看JSONModel的页面:http://www.jsonmodel.com

这也是创建基于JSON的应用程序的简单演练:http://www.touch-code-magazine.com/how-to-make-a-youtube-app-using-mgbox-and-jsonmodel/


在这里您还可以通过检查字符串的长度来做到这一点,即

1
2
3
4
if(tel.length==0)
{
    //do some logic here
}