我有一个非常简单的问题,我想有经验的人很容易回答。有一个JSON提要,可以将视频URL内容提供给我正在构建的其中一个应用程序。它看起来像这样:
{
"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"
}
要反序列化,我有以下代码:
-(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 =“http://somevideo1.mp4”;是可用的,但你可以看到我无法抓住它。我尝试使用NSString变量并尝试在记录之前为其分配[videoTypesItems objectForKey:@“uri”],但这也无效。解析这个JSON我在哪里出错了?谢谢你的阅读。
答案 0 :(得分:3)
您的videoTypes
字典没有任何嵌套数据。你想要这样的东西:
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
}
答案 1 :(得分:1)
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
}
在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"]);
}