从 iPhone 上的 .Net Web 服务解析 JSON



我调用一个网络服务,从中检索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,反过来可以转换为intfloatBOOL或任何其他有效的 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];
}

如果您需要更多帮助,请告诉我。

最新更新