I’m using the YouTube API to very simply fetch some videos and display them in a UITableView in my iPhone app, however it causes my table to freeze momentarily when fetching videos.
I can call the code below to fetch the next 25 videos and it works great, but at some point during the fetch processes my UITableView freezes then after a few seconds it will startup again once the fetch is complete. Do you have any ideas as to how I can stop this?
NSURL *url = [[[feeds lastObject] nextLink] URL];
GDataQueryYouTube* query = [GDataQueryYouTube youTubeQueryWithFeedURL:url];
ticket = [service fetchFeedWithQuery:query delegate:self didFinishSelector:@selector(requestAdditional:finishedWithFeed:error:)];
- (void)requestAdditional:(GDataServiceTicket *)ticket finishedWithFeed:(GDataFeedBase *)aFeed error:(NSError *)error
{
[feeds addObject:aFeed];
NSArray *newEntries = [aFeed entries];
for (GDataEntryBase *entry in newEntries)
{
[entry setParent:nil];
[feed addEntry:entry];
}
[self fetchVideoData];
[self dismissViewControllerAnimated:YES completion:^{}];
[self.tableView reloadData];
}
Edit
I think what causes the slow down is when I call [self fetchVideoData];. In this method I call a bunch of other methods which fetch all different bits of data, video title, view count, thumbnails etc.
I tried putting the bulk of this method inside the first section of the GCD method, then add my image object to my array in the latter part, but my array just comes out empty.
Here is an example of a particularly sluggish method, getting thew thumbnails. I have seen and tried but failed to apply the GCD method to this.
-(void)setThumbnailsArray
{
for (int i = 0; i < [[feed entries] count]; i++)
{
GDataEntryBase *entry = [[feed entries] objectAtIndex:i];
NSArray *thumbnails = [[(GDataEntryYouTubeVideo *)entry mediaGroup] mediaThumbnails];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[thumbnails objectAtIndex:1] URLString]]];
UIImage *image = [UIImage imageWithData:data];
//No thumbnail, create placeholder using avatar
if (image == nil)
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 110, 64)];
[view setBackgroundColor:[UIColor whiteColor]];
UIImageView *avatar = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"%@Avatar.png", memberName]]];
[avatar setFrame:CGRectMake(0, 0, avatar.frame.size.width - 10, avatar.frame.size.height - 10)];
avatar.center = view.center;
[view addSubview:avatar];
//Create UIImage from the view with the avatar
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
image = img;
}
[feedThumbnails addObject:image];
}
}
Are you making the calls to youtube on the main thread? If so, this will cause the UI to become unresponsive while that call is executing.
In general, you never want to perform time intensive operations on the main thread. Using Grand Central Dispatch, it would look something like this: