我调用一个网络服务,从中检索JSON。现在,JSON 是用户定义的,因此每个用户可能不同。问题是,如何在iOS中检查它是什么样的价值?(NSString,BOOL,NSNumber,NSDate等?
我收到的示例 JSON(已经进入 NSArray):
<__NSArrayM 0x119d11040>(
0000000010,
SomeName,
1, <--- boolean
SomeText,
3133,
<null>,
<null>,
<null>,
<null>,
0,
/Date(1321536126810)/,
SystemABC,
<null>,
<null>
)
(这是一个演示环境,<null>
很多值,但在生产中可以是字符串、数字、布尔值、日期等。
提前感谢!
如果您从服务器收到有效格式的 JSON,则可以使用该类将其序列化为某个字典/数组NSJSONSerialization
具体取决于 JSON 中设置的容器类型。序列化过程不仅会为您生成一个有效的容器(NSArray
/NSDictionary
),而且还会根据 JSON 本身中的类型分配包含的值,例如,引号值将包含在NSString
中,数字将包含在NSNumber
中,null 值将作为实例包含在NSNull
, 等。下面是一行简单的代码,它将有效的 JSON 转换为其等效的目标 C 容器类型,假设message
是从服务器发送的 JSON 的NSString
表示形式:
[NSJSONSerialization JSONObjectWithData:[message dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:NULL];
但是,对于 .NET Web 服务,日期将以带有前缀/Date
的字符串形式出现,序列化过程将假定它只不过是一个NSString
。因此,要在JSON中查找日期,您需要遍历解析的Objective-C数组/字典(可能使用for in
循环)以获取"/Date"前缀,然后将其手动转换为NSDate
。这段简单的代码应该可以为您解决问题:
if ([[str lowercaseString] hasPrefix:@"/date"]) { //str is a value in the parsed container with prefix /Date so assume that as date rather than a string
NSTimeInterval interval = [[NSNumber numberWithLongLong:[[[str stringByReplacingOccurrencesOfString:@"/date(" withString:@""] stringByReplacingOccurrencesOfString:@")/" withString:@""] longLongValue]] doubleValue] / 1000.0;
NSDate* dt = [NSDate dateWithTimeIntervalSince1970:interval];
//do whatever with dt now
}
最后,对于 .NET 数据类型,.NETnull
被分析为[NSNull null]
而不是nil
人们可能期望的。因此,在迭代时在容器中找到[NSNull null]
时,您应该假设nil
。此外,.NETbool
数据类型将被解析为 0/1,这只是一个NSNumber
,反过来可以转换为int
、float
、BOOL
或任何其他有效的 Objective C 数字格式,但除非他/她知道 JSON 的结构和数据类型,否则无法确定它是否最初是 .NETbool
, 提前。
尝试通过执行以下操作来记录[object class];
:NSLog(@"%@", NSStringFromClass(object.class));
如果您正在考虑解析 JSON,请尝试使用NSJSONSerialization
.请参阅:https://developer.apple.com/library/ios/documentation/foundation/reference/nsjsonserialization_class/Reference/Reference.html
对于日期,我有一个实用程序类,它有一些简单的方法来处理来自 .NET 的 SQL 日期。 下面是一个从 JSON 格式的日期开始创建 NSDate 对象的方法:
+ (NSDate *)nsDateFromDotNetJSONString:(id)object {
if ([object isKindOfClass:[NSDate class]]) {
return (NSDate *)object;
}
if (![object isKindOfClass:[NSString class]]) {
return nil;
}
NSString *string = (NSString *)object;
static NSRegularExpression *dateRegEx = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dateRegEx = [[NSRegularExpression alloc] initWithPattern:@"^\/date\((-?\d++)(?:([+-])(\d{2})(\d{2}))?\)\/$" options:NSRegularExpressionCaseInsensitive error:nil];
});
NSTextCheckingResult *regexResult = [dateRegEx firstMatchInString:string options:0 range:NSMakeRange(0, [string length])];
if (regexResult) {
// milliseconds
NSTimeInterval seconds = [[string substringWithRange:[regexResult rangeAtIndex:1]] doubleValue] / 1000.0;
// timezone offset
if ([regexResult rangeAtIndex:2].location != NSNotFound) {
NSString *sign = [string substringWithRange:[regexResult rangeAtIndex:2]];
// hours
seconds += [[NSString stringWithFormat:@"%@%@", sign, [string substringWithRange:[regexResult rangeAtIndex:3]]] doubleValue] * 60.0 * 60.0;
// minutes
seconds += [[NSString stringWithFormat:@"%@%@", sign, [string substringWithRange:[regexResult rangeAtIndex:4]]] doubleValue] * 60.0;
}
return [NSDate dateWithTimeIntervalSince1970:seconds];
}
return nil;
}
这是我用来获取 NSDate 和 SQL 格式的一个:
+(NSString *)sqlDateStringFromNSDate:(NSDate *)date {
if (date == nil) {
return @"";
}
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd hh:mm:ss"];
return [dateFormatter stringFromDate:date];
}
如果您需要更多帮助,请告诉我。