Ios 使用NSJSONSerialization正确反序列化嵌套JSON提要?
我有一个很简单的问题,我想有经验的人很容易回答。有一个JSON提要,它将视频URL内容传送到im构建中的一个应用程序。看起来是这样的:Ios 使用NSJSONSerialization正确反序列化嵌套JSON提要?,ios,json,cocoa-touch,ios6,Ios,Json,Cocoa Touch,Ios6,我有一个很简单的问题,我想有经验的人很容易回答。有一个JSON提要,它将视频URL内容传送到im构建中的一个应用程序。看起来是这样的: { "playlist": [ { "videos": { "ds900": { "length": 30, "bitrate": "900", "uri"
{
"playlist": [
{
"videos": {
"ds900": {
"length": 30,
"bitrate": "900",
"uri": "http://somevideo1.mp4"
},
"ds300": {
"length": 30,
"bitrate": "300",
"uri": "http://somevideo2.mp4"
},
"ds500": {
"length": 30,
"bitrate": "500",
"uri": "http://somevideo3.mp4"
},
"ds700": {
"length": 30,
"bitrate": "700",
"uri": "http://somevideo4.mp4"
}
}
}
],
"playlistName": "The Play List Name",
"description": "The description"
}
NSDictionary *videoTypes = [[playlistitems objectForKey:@"videos"] objectForKey:@"ds700"];
NSString *url = videoTypes[@"uri"];
NSLog(@"Val: %@", uri);
要对此进行反序列化,我有以下代码:
-(void)connectToVideoLink
{
NSString *urlString = @"http://Link_To_JSON_feed";
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *urlRequest =
[NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval:30.0f];
NSOperationQueue *queue =[[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:urlRequest
queue:queue
completionHandler:^(NSURLResponse *response,
NSData *dataR,
NSError *error) {
if([dataR length]>0 && error == nil)
{
NSString *feed = [[NSString alloc] initWithData:dataR
encoding:NSUTF8StringEncoding];
[self trythis2:dataR];
}
else if ([dataR length]==0 && error==nil)
{
NSLog(@"Nothing available");
}
else if (error != nil)
{
NSLog(@"Error is : %@", error);
}
}];
}
然后调用函数[self-trythis2:dataR];这将调用反序列化方法
-(void)trythis2:(NSData*)responseData
{
NSError *e = nil;
id jsonObject = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&e];
NSDictionary *jsonArray = (NSDictionary *)jsonObject;
jsonArray = [NSJSONSerialization JSONObjectWithData: responseData options: NSJSONReadingAllowFragments error: &e];
//NSArray
if (!jsonArray) {
NSLog(@"Error parsing JSON: %@", e);
} else {
NSArray *playlistdict = [jsonArray objectForKey:@"playlist"];
for (NSDictionary *playlistitems in playlistdict) {
NSDictionary *videoTypes = [[playlistitems objectForKey:@"videos"] objectForKey:@"ds700"];
NSLog(@"String: %@", videoTypes);
for (NSDictionary *videoTypesItems in videoTypes) {
NSLog(@"ds700 Key: %@", videoTypesItems);
NSLog(@"Val : %@",[videoTypesItems objectForKey:@"uri"]); //error caused here
}
}
}
}
如上所述,错误停止在注释行。这是我的输出:
2013-08-07 15:21:22.711 DeserializeJSON[3025:1d03] String: {
bitrate = 700;
length = 30;
uri = "http://somevideo1.mp4";
}
2013-08-07 15:21:22.713 DeserializeJSON[3025:1d03] ds700 Key: bitrate
2013-08-07 15:21:22.714 DeserializeJSON[3025:1d03] -[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x1ed3e910
2013-08-07 15:21:22.715 DeserializeJSON[3025:1d03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x1ed3e910'
*** First throw call stack:
(0x33e853e7 0x3bb80963 0x33e88f31 0x33e8764d 0x33ddf208 0x72ee9 0x71fa3 0x3471c229 0x34713a89 0x3478bfe7 0x3bf9a793 0x3bf9e657 0x3bf9e7d9 0x3bfc27f1 0x3bfc2684)
libc++abi.dylib: terminate called throwing an exception
(lldb)
我确信uri=“”;是可用的,但正如你所看到的,我不能抓住它。我尝试使用NSString变量,并在记录它之前尝试将[videoTypesItems objectForKey:@“uri”]分配给它,但这也不起作用。我在解析这个JSON时哪里出错了?感谢阅读。您的
videoTypes
词典没有任何嵌套数据。你想要这样的东西:
{
"playlist": [
{
"videos": {
"ds900": {
"length": 30,
"bitrate": "900",
"uri": "http://somevideo1.mp4"
},
"ds300": {
"length": 30,
"bitrate": "300",
"uri": "http://somevideo2.mp4"
},
"ds500": {
"length": 30,
"bitrate": "500",
"uri": "http://somevideo3.mp4"
},
"ds700": {
"length": 30,
"bitrate": "700",
"uri": "http://somevideo4.mp4"
}
}
}
],
"playlistName": "The Play List Name",
"description": "The description"
}
NSDictionary *videoTypes = [[playlistitems objectForKey:@"videos"] objectForKey:@"ds700"];
NSString *url = videoTypes[@"uri"];
NSLog(@"Val: %@", uri);
如果确实要迭代字典的键,可以执行以下操作:
NSDictionary *videoTypes = [[playlistitems objectForKey:@"videos"] objectForKey:@"ds700"];
NSLog(@"String: %@", videoTypes);
for (NSString *videoTypeKey in [videoTypes allKeys]) {
NSLog(@"ds700 Key: %@", videoTypeKey);
NSLog(@"Val : %@", videoTypesItems[videoTypeKey]); //error caused here
}
您的
videoTypes
词典没有任何嵌套数据。你想要这样的东西:
{
"playlist": [
{
"videos": {
"ds900": {
"length": 30,
"bitrate": "900",
"uri": "http://somevideo1.mp4"
},
"ds300": {
"length": 30,
"bitrate": "300",
"uri": "http://somevideo2.mp4"
},
"ds500": {
"length": 30,
"bitrate": "500",
"uri": "http://somevideo3.mp4"
},
"ds700": {
"length": 30,
"bitrate": "700",
"uri": "http://somevideo4.mp4"
}
}
}
],
"playlistName": "The Play List Name",
"description": "The description"
}
NSDictionary *videoTypes = [[playlistitems objectForKey:@"videos"] objectForKey:@"ds700"];
NSString *url = videoTypes[@"uri"];
NSLog(@"Val: %@", uri);
如果确实要迭代字典的键,可以执行以下操作:
NSDictionary *videoTypes = [[playlistitems objectForKey:@"videos"] objectForKey:@"ds700"];
NSLog(@"String: %@", videoTypes);
for (NSString *videoTypeKey in [videoTypes allKeys]) {
NSLog(@"ds700 Key: %@", videoTypeKey);
NSLog(@"Val : %@", videoTypesItems[videoTypeKey]); //error caused here
}
在videoTypes
中,您正在打开“ds700”字典。它不包含任何子字典,仅包含键值对。但是,for循环正在创建NSDictionary
"ds700": {
"length": 30,
"bitrate": "700",
"uri": "http://somevideo4.mp4"
}
如果要循环浏览所有不同的视频类型(ds300、ds500、ds700和ds900),请尝试以下操作:
NSDictionary *videoTypes = [[playlistitems objectForKey:@"videos"];
NSLog(@"String: %@", videoTypes);
for (NSDictionary *videoTypesItems in videoTypes) {
NSLog(@"type Key: %@", videoTypesItems);
NSLog(@"Val : %@",[videoTypesItems objectForKey:@"uri"]);
}
在videoTypes
中,您正在打开“ds700”字典。它不包含任何子字典,仅包含键值对。但是,for循环正在创建NSDictionary
"ds700": {
"length": 30,
"bitrate": "700",
"uri": "http://somevideo4.mp4"
}
如果要循环浏览所有不同的视频类型(ds300、ds500、ds700和ds900),请尝试以下操作:
NSDictionary *videoTypes = [[playlistitems objectForKey:@"videos"];
NSLog(@"String: %@", videoTypes);
for (NSDictionary *videoTypesItems in videoTypes) {
NSLog(@"type Key: %@", videoTypesItems);
NSLog(@"Val : %@",[videoTypesItems objectForKey:@"uri"]);
}
你为什么把字典叫做“jsonArray”?在你来到这里之前你做得很好--
for(NSDictionary*videoTypesItems in videoTypes){
您好,是的,我不想让您感到困惑。因为我在NSArray和NSDictionary之间玩游戏,所以在发布之前忘了更改名称。谢谢您指出这一点。在处理JSON“解构”时,使用有意义的名称是非常关键的。同时请注意术语“嵌套JSON”通常是在JSON结构包含一个本身是有效JSON序列的(带引号的)字符串的情况下保留的。上面是一个相对简单的JSON结构,而不是按照该定义“嵌套”的。为什么要将字典称为“jsonArray”?在这里之前你做得很好--(NSDictionary*videoTypesItems in videoTypes){
您好,是的,我不想把您弄糊涂。我在发布之前忘了更改名称,因为我在NSArray和NSDictionary之间玩。不过感谢您指出这一点。在处理JSON“解构”时,这非常关键,以使用有意义的名称。还请注意,术语“嵌套的JSON”通常用于JSON结构包含(带引号的)字符串的情况,该字符串本身是一个有效的JSON序列。以上是一个相对简单的JSON结构,而不是“嵌套的”根据这个定义。谢谢你的回答,Bo A。我尝试了你的解决方案,它看起来像是我以前实施的类似解决方案。它导致了相同的问题。谢谢你的回答,Bo A。我尝试了你的解决方案,它看起来像是我以前实施的类似解决方案。它导致了相同的问题。谢谢你的解决方案,我能够抓住问题URL。由于videoTypes目前是一个字典。videoTypes[@“uri”]和[videoTypesItems objectForKey:@“uri”]不是做同样的事情吗?除了前者似乎被视为数组之外?使用videoTypes[@“uri”]
是现代语法,本质上与[videoTypes objectForKey:@“uri”]
。感谢您提供的解决方案,我能够获取URL。因为videoTypes目前是一个字典。videoTypes[@“uri”]和[videoTypesItems objectForKey:@“uri”]不是做同样的事情吗?除了前者似乎被视为数组之外?使用videoTypes[@“uri”]
是现代语法,本质上与[videoTypes objectForKey:@“uri”]
。