2014-06-11 104 views
0

我在解析YouTube上的JSON时遇到问题。我试图获取标题,videoId和默认缩略图网址。我之前解析过JSON,但是我遇到问题,无法从中获得我想要的内容。解析YouTube JSON

这是我的代码。它具有无法识别的选择错误而崩溃的NSDictionary* snippet = [item objectForKey:@"snippet"];的错误是-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x108781b0

#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 
#define storeURL [NSURL URLWithString: @"https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=25&playlistId=UUkfYL7q5G8CYtZgtSAwmwzw&key=AIzaSyBS4do208_KPGHAhszfVkHadSvtfSgr7Mo"] 

#import "KFBYoutubeVideosTableViewController.h" 
#import "SVProgressHUD.h" 
#import "Reachability.h" 
#import "TSMessage.h" 
#import "TSMessageView.h" 

@interface KFBYoutubeVideosTableViewController() 

@end 

@implementation KFBYoutubeVideosTableViewController 
@synthesize title, videoID, thumbURL, url, titleArray, videoIDArray, thumbArray; 

- (id)initWithStyle:(UITableViewStyle)style 
{ 
    self = [super initWithStyle:style]; 
    if (self) { 

    } 
    return self; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    [[SVProgressHUD appearance]setHudBackgroundColor:[UIColor blackColor]]; 
    [[SVProgressHUD appearance]setHudForegroundColor:[UIColor whiteColor]]; 
    [SVProgressHUD showWithStatus:@"Loading"]; 

    Reachability *networkReachability = [Reachability reachabilityForInternetConnection]; 
    NetworkStatus networkStatus = [networkReachability currentReachabilityStatus]; 

    if(networkStatus == NotReachable) 
    { 
     [TSMessage showNotificationWithTitle:@"Network Error" subtitle:@"No active network connection!" type:TSMessageNotificationTypeError]; 
     [SVProgressHUD dismiss]; 
    } 

    self.title = @"KFB Videos"; 

    self.tableView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStyleGrouped]; 
    self.tableView.backgroundColor = [UIColor darkGrayColor]; 

    url = [NSURL URLWithString:@"https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=25&playlistId=UUkfYL7q5G8CYtZgtSAwmwzw&key=AIzaSyBS4do208_KPGHAhszfVkHadSvtfSgr7Mo"]; 

    dispatch_async(kBgQueue, ^{ 
     NSData *data = [NSData dataWithContentsOfURL:url]; 
     if (data == nil) 
     { 
      NSLog(@"data is nil"); 
     } 
     else 
     { 
      [self performSelectorOnMainThread:@selector(fetchedData:) withObject:data waitUntilDone:YES]; 
     } 
    }); 
} 

- (void)viewDidDisappear:(BOOL)animated 
{ 
    [SVProgressHUD dismiss]; 
} 

- (void)fetchedData:(NSData *)responseData 
{ 
    NSError *error; 
    titleArray = [[NSMutableArray alloc]init]; 
    videoIDArray = [[NSMutableArray alloc]init]; 
    thumbArray = [[NSMutableArray alloc]init]; 

    NSArray *json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error]; 
    NSLog(@"%@", json); 

    for (NSDictionary *item in json) 
    { 
     NSDictionary* snippet = [item objectForKey:@"snippet"]; 
     title = [snippet objectForKey:@"title"]; 
     videoID = [[snippet objectForKey:@"resourceId"] objectForKey:@"videoID"]; 
     thumbURL = [[[snippet objectForKey:@"thumbnails"] objectForKey:@"default"] objectForKey:@"url"]; 

     [titleArray addObject:title]; 
     [videoIDArray addObject:videoID]; 
     [thumbArray addObject:thumbURL]; 
    } 

    [self.tableView reloadData]; 
    [SVProgressHUD dismiss]; 
} 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return [titleArray count]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; 
    if (cell == nil) 
    { 
     cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Cell"]; 
     cell.textLabel.font = [UIFont systemFontOfSize:16.0]; 
    } 
    if (cell) 
    { 
     cell.backgroundColor = [UIColor clearColor]; 
     cell.textLabel.text = [titleArray objectAtIndex:indexPath.row]; 
     cell.textLabel.textColor = [UIColor blackColor]; 
    } 
    return cell; 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSLog(@"Title: %@, Video ID: %@, Thumbnail URL: %@", [titleArray objectAtIndex:indexPath.row],[videoIDArray objectAtIndex:indexPath.row], [thumbArray objectAtIndex:indexPath.row]); 

    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

@end 

这里是JSON:

{ 
    etag = "\"bvxF-DWHx1toJotsdJBeCm43SLs/tyIRY5zDT7R6YEirBFeFh0tVLCw\""; 
    items =  (
       { 
      etag = "\"bvxF-DWHx1toJotsdJBeCm43SLs/ON_wGC8nyy0H_bqRqQHlA7mXiM0\""; 
      id = UUstIg9nSlWxTaKpWq7G0sppJf9oH5NaDE; 
      kind = "youtube#playlistItem"; 
      snippet =    { 
       channelId = UCkfYL7q5G8CYtZgtSAwmwzw; 
       channelTitle = "Kentucky Farm Bureau"; 
       description = "Celebrate June as National Dairy Month with a visit to Jericho Acres Dairy Farm in Henry County."; 
       playlistId = UUkfYL7q5G8CYtZgtSAwmwzw; 
       position = 0; 
       publishedAt = "2014-05-22T12:28:03.000Z"; 
       resourceId =     { 
        kind = "youtube#video"; 
        videoId = VSCr40jERks; 
       }; 
       thumbnails =     { 
        default =      { 
         height = 90; 
         url = "https://i1.ytimg.com/vi/VSCr40jERks/default.jpg"; 
         width = 120; 
        }; 
        high =      { 
         height = 360; 
         url = "https://i1.ytimg.com/vi/VSCr40jERks/hqdefault.jpg"; 
         width = 480; 
        }; 
        maxres =      { 
         height = 720; 
         url = "https://i1.ytimg.com/vi/VSCr40jERks/maxresdefault.jpg"; 
         width = 1280; 
        }; 
        medium =      { 
         height = 180; 
         url = "https://i1.ytimg.com/vi/VSCr40jERks/mqdefault.jpg"; 
         width = 320; 
        }; 
        standard =      { 
         height = 480; 
         url = "https://i1.ytimg.com/vi/VSCr40jERks/sddefault.jpg"; 
         width = 640; 
        }; 
       }; 
       title = "Kentucky Farm Bureau Reports June 2014"; 
      }; 
     }, 

回答

2

如果你仔细观察标题是不是在JSON响应的底部。这些节点的每个人都是一本字典。所以为了让你从你的代码想要的东西,你必须这样做:

NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error]; 
NSArray *items = [json objectForKey:@"items"]; 
for (NSDictionary *item in json) 
{ 
    NSDictionary* snippet = [item objectForKey:@"snippet"]; 
    title = [snippet objectForKey:@"title"]; 
    videoID = [[snippet objectForKey:@"resourceId"] objectForKey:@"videoId"]; 
    thumbURL = [[[snippet objectForKey:@"thumbnails"] objectForKey:@"default"] objectForKey:@"url"]; 
} 

如果你打算做更多的东西,这个数据我建议你创建对象和创建每个对象时解析JSON。所以你可以在将来跟踪其他属性。这样就更清洁了。

+0

该应用程序在NSDictionary * snippet = [item objectForKey:@“snippet”];上无法识别的选择器错误崩溃; – raginggoat

+1

我已经更新了我的回复。你得到的json对象是一个NSDictionary而不是一个Array,所以你首先必须从那里获取items数组,然后你可以迭代它。 –

+0

已修复大部分内容,但videoID为NULL。 – raginggoat