Getting reddit feed as JSON and parsing it - xcode

I'm trying to parse JSON feed from reddit.com and then display it in a tableview. The JSON looks like this:
{
kind: Listing
data: {
modhash: 3lmt2d4hq6797af804da91bde566bd067ddee68e1e7f8e0dda
children: [
{
kind: t3
data: {
domain: imgur.com
banned_by: null
media_embed: { }
subreddit: funny
selftext_html: null
selftext:
likes: null
link_flair_text: null
id: 16e9so
clicked: false
title: I left my dog unattended with the 2 year old...
num_comments: 166
score: 2213
approved_by: null
over_18: false
hidden: false
thumbnail: http://c.thumbs.redditmedia.com/DaoiOlvtdjaPBG3n.jpg
subreddit_id: t5_2qh33
edited: false
link_flair_css_class: null
author_flair_css_class: null
downs: 2481
saved: false
is_self: false
permalink: /r/funny/comments/16e9so/i_left_my_dog_unattended_with_the_2_year_old/
name: t3_16e9so
created: 1357963292
url: http://imgur.com/zGMxP
author_flair_text: null
author: ShaneNickerson
created_utc: 1357934492
media: null
num_reports: null
ups: 4694
}
...more items here
}
And here's my tableview controller code:
#import "mainRedditFunViewController.h"
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#define kjsonURL [NSURL URLWithString: #"http://reddit.com/r/funny/.json"
#interface mainRedditFunViewController ()
#end
#implementation mainRedditFunViewController
- (void)viewDidLoad
{
[super viewDidLoad];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://reddit.com/r/funny/.json"]];
[self performSelectorOnMainThread:#selector(fetchedData:)
withObject:data waitUntilDone:YES];
});
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] ;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
NSDictionary *appsdict = [jsonResults objectAtIndex:indexPath.row];
NSString *VersionString = [appsdict objectForKey:#"url"];
NSString *priceString = [appsdict objectForKey:#"author"];
NSURL *imageURL = [NSURL URLWithString:[appsdict objectForKey:#"thumbnail"]];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *imageLoad = [[UIImage alloc] initWithData:imageData];
cell.textLabel.text = [appsdict objectForKey:#"title"];
cell.detailTextLabel.text = [NSString stringWithFormat:#"URL: %# Author: $ %# USD",VersionString,priceString];
cell.imageView.image = imageLoad;
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [jsonResults count];
}
- (void)fetchedData:(NSData *)responseData {
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
jsonResults = [json objectForKey:#"data.children"];
[self.tableView reloadData];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
However, the output is completly empty. Is there anyway I could fix it? I tried it before with another (smaller) feed and it worked fine. I'm sure if I'm doing the JSONPath formatting correctly, since I'd look like that:
-kind
->data
->children
->data (my items)
->data
->data
...
I'd appreciate any help I get!

Im sorry that this answer is late! hope that it is still needed...
I have altered your code a little bit to access the sub levels of the returned Json results.
You certainly have the right Idea but just need a few more dictionaries in your fetchedData method. If you add these dictionaries in you method underneath your NSJSONSerialization;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:&error];
//NSArray *Fullarray = [[NSArray alloc] initWithObjects:json, nil];
_jsonResult = [[NSMutableArray alloc] init];
NSDictionary *dataDict = [json objectForKey:#"data"];
NSDictionary *chilrenDict = [dataDict objectForKey:#"children"];
for (NSDictionary *informationFromChild in chilrenDict) {
NSLog(#"chil %#", chilrenDict);
[_jsonResult addObject:chilrenDict];
}
Then in your tableView cellForRow change your appsDict to this
NSDictionary *appsdict = [[_jsonResult objectAtIndex:indexPath.row] objectForKey:#"data"];
That should fix up the code and populate the tableView...
You can run a check on this too by checking
NSLog(#"count %i", [_jsonResult count]);
Let me know if this has been of help, happy coding. T

Related

NSMutableArray have error empty array

i have some problem with NSMutablearray and JSON parse.
So what i doing? A make parse from JSON and send to my TableViewCell.
I have my code:
h:
{
NSMutableData *webdata;
NSURLConnection *connection;
NSMutableArray *array;
NSMutableArray *array2;
NSTimer *timer;
}
m:
{
[super ViewDidload]
[[self tableTrack] setDelegate:self];
[[self tableTrack] setDataSource:self];
array = [[NSMutableArray alloc] init];
array2 = [[NSMutableArray alloc] init];
timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(plistGet) userInfo:nil repeats:YES];
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[webdata setLength:0];
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[webdata appendData:data];
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(#"error load");
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSDictionary *allDataDictionary = [NSJSONSerialization JSONObjectWithData:webdata options:0 error:nil];
NSDictionary *playlist =[allDataDictionary objectForKey:#"playlist"];
for (NSDictionary *diction in playlist) {
NSDictionary *artist = [diction objectForKey:#"artist"];
NSDictionary *song = [diction objectForKey:#"song"];
NSString *name = [artist objectForKey:#"name"];
NSString *namesong = [song objectForKey:#"name"];
[array addObject:name];
[array2 addObject:namesong];
}
[[self tableTrack]reloadData];
}
-(void)plistGet {
[array removeAllObjects];
[array2 removeAllObjects];
NSURL *url = [NSURL URLWithString:#"http://plist.json"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
connection = [NSURLConnection connectionWithRequest:request delegate:self];
if (connection) {
webdata = [[NSMutableData alloc]init];
}
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [array count];
// return [array2 count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(! cell)
{
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]autorelease];
}
cell.textLabel.text = [array2 objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [array objectAtIndex:indexPath.row];
cell.textLabel.textColor = [UIColor colorWithRed:(50/255.0) green:(200/255.0) blue:(255/255.0) alpha:1];
[tableTrack setBackgroundView:nil];
tableTrack.backgroundColor = [UIColor clearColor];
cell.detailTextLabel.font=[UIFont fontWithName: #"Helvetica" size:11];
UIFont *myFont = [ UIFont fontWithName: #"Arial" size: 9.0 ];
cell.textLabel.font = myFont;
self.tableTrack.separatorStyle = UITableViewCellSeparatorStyleNone;
UIView *separatorView = [[UIView alloc] initWithFrame:CGRectMake(0, 43, 1024, 1)];
separatorView.layer.borderColor = [UIColor darkGrayColor].CGColor;
separatorView.layer.borderWidth = 0.5;
[cell.contentView addSubview:separatorView];
return cell;
}
All work very good but after 5 or 3 minutes i have error and my app crashed.
Error:
2013-06-21 12:32:41.502 EuropaPlusUA[651:707] * Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
* First throw call stack:
(0x353f188f 0x37798259 0x3533a9db 0xfa9d5 0x32e85efb 0x32e84fd9 0x32e84763 0x32e28f37 0x353501fb 0x32220aa5 0x322206bd 0x32224843 0x3222457f 0x3221c4b9 0x353c5b1b 0x353c3d57 0x353c40b1 0x353474a5 0x3534736d 0x36fe3439 0x32e53cd5 0xf8843 0xf87d0)
terminate called throwing an exception
What is it? Help please.
Your problem is that you probably do another plistget method after that 3-5 minutes. That method will throw away all objects from your array. During the time your data is getting loaded and the time you cleared your array, the table datasource is empty, however you are trying to get this object from index 0. This is why your crash happens.
The solution however is simple. Do not call the removeAllObjects method at all.
Simply replace the array with the contents that you will retrieve.
Replace mechanic that you will need to do the moment you get the data from your server:
NSMutableArray *tempDataArray = [[NSMutableArray alloc] init];
//put retrieved data from your web call in the tempDataArray
array = tempDataArray;
me thinks the only objectAtIndex is here.
cell.detailTextLabel.text = [array objectAtIndex:indexPath.row];
seems likely array was emptied by plistget
[array removeAllObjects];
Totumus Maximus is right.
If you just need to bridge the gap between getting clearing the arrays and reloading the data why not try NOT deleting them until the new data is ready? Then just replace them
Alternatively make a copy of them first (say to backUpArray and backUpArray2) and then check to see if you have data in array/array2 (something like if([array count]) or if (array) {...) before you try and load the cell.
If you have nothing in the arrays use [backUpArray lastObject] to give you some data for the (brief ?) time until the arrays are reloaded.

Need help on update and delete sqlite on the tableview

I'm a beginner on xcode and I have very little knowledge about it. Here is my code. I'm doing a simple account management program for iOS 6.0. I need to select the row from where i'm going to edit/delete my data from the table view and then be able to update/delete it. I don't know how to code those and I need help from experienced programmers.
My project: http://www.mediafire.com/?95l8pwzu3c62ts0
#import "FlipsideViewController.h"
#interface FlipsideViewController ()
#end
#implementation FlipsideViewController
#synthesize entries;
- (void)viewDidLoad
{
self.label.text=self.strUsername;
entries = [[NSMutableArray alloc]init];
[self openDB];
NSString *sql = [NSString stringWithFormat:#"SELECT * FROM SUMMARY8 WHERE theuser = '%s'",[self.label.text UTF8String]];
sqlite3_stmt *statement;
if (sqlite3_prepare(account, [sql UTF8String], -1, &statement, nil)==SQLITE_OK)
{
while (sqlite3_step(statement)==SQLITE_ROW){
char *field1=(char *) sqlite3_column_text(statement, 0 );
NSString *field1Str = [[NSString alloc]initWithUTF8String:field1];
char *field2=(char *) sqlite3_column_text(statement, 1 );
NSString *field2Str = [[NSString alloc]initWithUTF8String:field2];
char *field3=(char *) sqlite3_column_text(statement, 2 );
NSString *field3Str = [[NSString alloc]initWithUTF8String:field3];
char *field4=(char *) sqlite3_column_text(statement, 3 );
NSString *field4Str = [[NSString alloc]initWithUTF8String:field4];
NSString *str = [[NSString alloc]initWithFormat:#"%# - %# - %#", field1Str,field3Str,field4Str];
[entries addObject:str];
}
}
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(NSString *) filePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return [[paths objectAtIndex:0]stringByAppendingPathComponent:#"account.sql"];
}
-(void) openDB
{
if (sqlite3_open([[self filePath] UTF8String], &account) !=SQLITE_OK){
sqlite3_close(account);
NSAssert(0,#"Database failed to open");
}
else
{
NSLog(#"database opened");
}
}
- (IBAction)addaccount:(id)sender {
MainViewController *FVC = [self.storyboard instantiateViewControllerWithIdentifier:#"MainViewController"];
FVC.strUsername=self.strUsername;
[self presentViewController:FVC animated:YES completion:nil];
// FVC.label.text=self.label.text;
}
- (IBAction)btnEdit:(id)sender {
}
- (IBAction)btnDelete:(id)sender {
[self tableView:<#(UITableView *)#> cellForRowAtIndexPath:<#(NSIndexPath *)#>];
}
#pragma mark - Actions
- (IBAction)done:(id)sender
{
[self.delegate flipsideViewControllerDidFinish:self];
}
-(NSInteger) numberOfSectionsInTableView: (UITableView *)tableView
{
return 1;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSString *myTitle = [[NSString alloc]initWithFormat:#"Name - Username - Password"];
return myTitle;
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"%d", [entries count]);
return [entries count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{//NSLog(#"test");
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = [self.entries objectAtIndex:indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *selectedRow = [entries objectAtIndex:indexPath.row];
NSString *sql = [NSString stringWithFormat:#"DELETE FROM SUMMARY8 WHERE name = '%#'",selectedRow];
char *err;
if (sqlite3_exec(account, [sql UTF8String], NULL, NULL, &err)!=SQLITE_OK){
sqlite3_close(account);
NSAssert(0, #"Could not delete row");
}
else {
NSLog(#"row deleted");
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Done" message:#"Account was deleted successfully!" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}
#end
is this correct? sorry I absolutely have no background on Xcode. So sorry for the bother..
Delete use this:
Example:strUpdate = [NSString stringWithFormat:#"DELETE FROM SUMMARY8 WHERE theuser = '%s'",[self.label.text UTF8String]];
Update use this:
Example(updating the status):strQuery = [NSString stringWithFormat:#"UPDATE SUMMARY8 SET STATUS='1' WHERE theuser = '%s'",[self.label.text UTF8String]];
Hope this helps.
EDIT:
use this method:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
Example: NSString *selectedRow = [entries objectAtIndex:indexPath.row];
}
This method basically shows the data for that row of table. manipulate with that data. Given examples.. Tweak it according to your situation...
EDIT 2:
For example:
UITableView *table = [[UITableView alloc] init];
[self tableView:table didSelectRowAtIndexPath:index];
where index is your item number.

TWRequest from a dictionary in a tableView Cell

I am trying to propagate a table view with a custom cell with the results of a TWRequest with no luck. I am trying to store the tweets in a dictionary object then calling an ObjectAtKey request and putting into a string. Here is my code - any help would be appreciated. Thanks -
-(void)fetchTweets
{
// Do a simple search, using the Twitter API
TWRequest *request = [[TWRequest alloc] initWithURL:[NSURL URLWithString:
#"http://search.twitter.com/search.json?q=iOS%205&rpp=5&with_twitter_user_id=true&result_type=recent"]
parameters:nil requestMethod:TWRequestMethodGET];
// Notice this is a block, it is the handler to process the response
[request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error)
{
if ([urlResponse statusCode] == 200)
{
// The response from Twitter is in JSON format
// Move the response into a dictionary and print
NSError *error;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];
NSLog(#"Twitter response: %#", dict);
}
else
NSLog(#"Twitter error, HTTP response: %i", [urlResponse statusCode]);
}];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return tweets.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSString *tweetText = [dict objectForKey:#"text"];
NSArray *tweetComponents = [tweetText componentsSeparatedByString:#":"];
cell.Header.text = [tweetComponents objectAtIndex:0];
cell.Details.text = [tweetComponents objectAtIndex:1];
cell.Date.text = [tweetComponents objectAtIndex:2];
return cell;
}
You will need to create an NSMutableArray of the tweets from the Twitter response.
Each tweet being a separate object.
NSMutableArray *resultArray = [[NSMutableArray] alloc] init];
for (NSDictionary *tweet in dict)
{
[resultArray addObject:tweet];
}
Then in cellForRowAtIndexPath retrieve the object based on the row of the table, something like
TweetResult *tweetResult [resultArray objectAtIndex:[indexPath row]];

Custom cells - how can I separate out tweets into componentsseparatedbyString

I have a custom cell in a tableview. All connections are made. I am conducting a Twitter search. The results of this propagate a custom cell in a tableView. I would like to separate the individual tweets out into an array using componentsseparatedbystring so that I can assign these to 4 labels in my custom cell. Any help would be greatly appreciated. Here is my code.
- (void)fetchTweets
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData* data = [NSData dataWithContentsOfURL:
[NSURL URLWithString: #"https://api.twitter.com/1/statuses/public_timeline.json"]];
NSError* error;
tweets = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
});
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return tweets.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TweetCell";
customCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
// added this bit in
cell = [[customCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// THIS IS THE BIT I'M STRUGGLING WITH
// I'M GUESSING THAT THIS LINE SEPARATES THE TWEETS INTO SINGLE TWEETS?
NSDictionary *tweet = [tweets objectAtIndex:indexPath.row];
// I THEN CREATE AN ARRAY TO HOLD MY COMPONENTS OF THE TWEET SO THAT I CAN SPLIT FOR MY LABELS
NSArray *arrayForCustomCell = [[NSArray alloc] init];
arrayForCustomCell = [tweet componentsSeparatedByString:#":"];
return cell;
}
You have already parsed the results in your async call. Now, you have an array of 'tweet' dictionaries and you can grab any value like this:
NSDictionary *tweet = [tweets objectAtIndex:indexPath.row];
NSString *tweetText = [tweet valueForKey:#"text"];
NSString *tweetCountry = [tweet valueForKeyPath:#"place.country"] //Nested property
and then you just set your UILabels. You get the idea...

How to solve slow scrolling in UITableView - using the YouTube API

I'm working with the google YouTube API, and I'm using this code found here http://pastebin.com/vmV2c0HT
The Code that slows things down is this one here
cell.imageView.image = [UIImage imageWithData:data];
When I remove that code it scrolls smoothly. Any idea on how I can go about having it load the images from google but still scroll smoothly? I've read some of the answers on loading images in a different way, but I still can't figure out how I'll make that work with the code I'm using.
Any help will be appreciated.
Bellow is the full code.
#import "RootViewController.h"
#interface RootViewController (PrivateMethods)
- (GDataServiceGoogleYouTube *)youTubeService;
#end
#implementation RootViewController
#synthesize feed;
- (void)viewDidLoad {
NSLog(#"loading");
GDataServiceGoogleYouTube *service = [self youTubeService];
NSString *uploadsID = kGDataYouTubeUserFeedIDUploads;
NSURL *feedURL = [GDataServiceGoogleYouTube youTubeURLForUserID:#"BmcCarmen"
userFeedID:uploadsID];
[service fetchFeedWithURL:feedURL
delegate:self
didFinishSelector:#selector(request:finishedWithFeed:error:)];
[super viewDidLoad];
}
- (void)request:(GDataServiceTicket *)ticket
finishedWithFeed:(GDataFeedBase *)aFeed
error:(NSError *)error {
self.feed = (GDataFeedYouTubeVideo *)aFeed;
[self.tableView reloadData];
}
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[feed entries] count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
GDataEntryBase *entry = [[feed entries] objectAtIndex:indexPath.row];
NSString *title = [[entry title] stringValue];
NSArray *thumbnails = [[(GDataEntryYouTubeVideo *)entry mediaGroup] mediaThumbnails];
cell.textLabel.text = title;
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[thumbnails objectAtIndex:0] URLString]]];
cell.imageView.image = [UIImage imageWithData:data];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 100.0f;
}
- (void)dealloc {
[super dealloc];
}
- (GDataServiceGoogleYouTube *)youTubeService {
static GDataServiceGoogleYouTube* _service = nil;
if (!_service) {
_service = [[GDataServiceGoogleYouTube alloc] init];
[_service setShouldCacheDatedData:YES];
[_service setServiceShouldFollowNextLinks:YES];
}
// fetch unauthenticated
[_service setUserCredentialsWithUsername:nil
password:nil];
return _service;
}
#end
GCD is a wonderful thing. Here is what I do:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"youTubeCell";
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell.
GDataEntryBase *entry = [[feed entries] objectAtIndex:indexPath.row];
NSString *title = [[entry title] stringValue];
NSArray *thumbnails = [[(GDataEntryYouTubeVideo *)entry mediaGroup] mediaThumbnails];
cell.textLabel.text = title;
// Load the image with an GCD block executed in another thread
dispatch_queue_t downloadQueue = dispatch_queue_create("image downloader", NULL);
dispatch_async(downloadQueue, ^{
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[thumbnails objectAtIndex:0] URLString]]];
UIImage * image = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
cell.imageView.image = image;
cell.imageView.contentMode = UIViewContentModeScaleAspectFit;
[cell setNeedsLayout];
});
});
dispatch_release(downloadQueue);
return cell;
}
Scrolling is now super smooth. The only drawback is that when you scroll quickly, cells are re-used and sometimes the images change as new ones come in.

Resources