I am trying to parse JSON data with AFNetworking AFJSONRequestOperation. But i am getting an empty UITable for some reason.
I managed to do it without AFNetworking.
Could someone please have a look at my code Google Drive
#import "AFNetworking.h"
#import "AFJSONRequestOperation.h"
#interface KKViewController ()
#end
#implementation KKViewController
#synthesize movies = _movies, count = _count;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.movies = [[NSArray alloc] init];
// get data from youtube
NSURL *url = [[NSURL alloc] initWithString:#"http://gdata.youtube.com/feeds/api/playlists/PL0l3xlkh7UnvLdr0Zz3XZZuP2tENy_qaP?v=2&alt=jsonc&max-results=50"];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
self.movies = [JSON valueForKeyPath:#"data.items.video"];
// NSLog(##, video)
//
self.count = [JSON valueForKeyPath:#"data.items.video.thumbnail"];
[self.activityIndicatorView stopAnimating];
[self.tableView setHidden:NO];
[self.tableView reloadData];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(#"Request Failed with Error: %#, %#", error, error.userInfo);
}];
[operation start];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 0;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
if (self.movies && self.movies.count) {
return self.movies.count;
} else {
return 0;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = #"Cell Identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];
}
NSDictionary *movie = [self.movies objectAtIndex:indexPath.row];
NSDictionary *countt = [self.count objectAtIndex:indexPath.row];
cell.textLabel.text = [movie objectForKey:#"title"];
cell.detailTextLabel.text = [movie objectForKey:#"uploader"];
NSURL *url = [[NSURL alloc] initWithString:[countt objectForKey:#"hqDefault"]];
[cell.imageView setImageWithURL:url placeholderImage:[UIImage imageNamed:#"placeholder"]];
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
#end
[1]: https://docs.google.com/folder/d/0B1EPIKZI6a5sSzVWdXh6VU1POWs/edit?usp=sharing
you should move you initiation code from viewDidLoad to viewWillAppear
numberOfSectionInTableView should return 1 and not 0
Related
Both of the NSLog's in viewWillAppear and numberOfRowsInSection are showing the data I'd like to populated in the tableView.
I thought this problem had something to do with returning the correct count but, since the NSLogs match, I'm not sure that that's the problem.
Also, I figured that that was the problem because cellForRowAtIndexPath isn't being called.
Am I not reloading my tableView correctly? Thanks so much for the help.
#import "MainQueryViewController.h"
#import <Parse/Parse.h>
#import "SVProgressHUD.h"
#import "HHPanningTableViewCell.h"
#import "HHInnerShadowView.h"
#import "HHDirectionPanGestureRecognizer.h"
#interface MainQueryViewController () <PFLogInViewControllerDelegate, PFSignUpViewControllerDelegate, HHPanningTableViewCellDelegate>
#end
#implementation MainQueryViewController
#synthesize listArray;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
PFLogInViewController *login = [[PFLogInViewController alloc] init];
login.fields = PFLogInFieldsFacebook;
login.delegate = self;
login.signUpController.delegate = self;
[self presentModalViewController:login animated:NO];
}
-(void)viewWillAppear:(BOOL)animated {
PFQuery *query = [PFQuery queryWithClassName:#"ListItem"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
[query whereKey:#"listName" equalTo:[PFUser currentUser]];
listArray = [objects mutableCopy];
NSLog(#"I'm about to show you an array");
NSLog(#"%#", listArray);
}
else {
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
HHPanningTableViewCell *cell = (HHPanningTableViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSInteger directionMask = indexPath.row % 5;
if (cell == nil) {
NSLog(#"Cell = nil.");
cell = [[HHPanningTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
UIView *drawerView = [[UIView alloc] initWithFrame:cell.frame];
drawerView.backgroundColor = [UIColor greenColor];
cell.textLabel.text = [listArray objectAtIndex:indexPath.row];
cell.drawerView = drawerView;
// Configure the cell...
}
if (directionMask < 3) {
cell.directionMask = directionMask;
}
else {
cell.directionMask = HHPanningTableViewCellDirectionLeft + HHPanningTableViewCellDirectionRight;
if (directionMask == 4) {
cell.delegate = self;
}
}
cell.textLabel.text = [self.listArray objectAtIndex:directionMask];
return cell;
}
#pragma mark - PFLogInViewController delegate
- (void)logInViewController:(PFLogInViewController *)logInController didLogInUser:(PFUser *)user
{
[self dismissViewControllerAnimated:YES completion:^{
NSLog(#"Successfully logged in.");
[SVProgressHUD showSuccessWithStatus:#"Success!"];
}];
}
- (void)logInViewControllerDidCancelLogIn:(PFLogInViewController *)logInController
{
[self dismissModalViewControllerAnimated:YES];
NSLog(#"Login was cancelled!");
}
- (void)signUpViewController:(PFSignUpViewController *)signUpController didSignUpUser:(PFUser *)user
{
[self dismissModalViewControllerAnimated:YES];
NSLog(#"Successfully signed up.");
}
- (void)signUpViewControllerDidCancelSignUp:(PFSignUpViewController *)signUpController
{
[self dismissModalViewControllerAnimated:YES];
NSLog(#"Sign up was cancelled!");
}
#pragma mark - Table view delegate
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if ([cell isKindOfClass:[HHPanningTableViewCell class]]) {
HHPanningTableViewCell *panningTableViewCell = (HHPanningTableViewCell*)cell;
if ([panningTableViewCell isDrawerRevealed]) {
return nil;
}
}
return indexPath;
}
- (void)panningTableViewCellDidTrigger:(HHPanningTableViewCell *)cell inDirection:(HHPanningTableViewCellDirection)direction
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Custom Action"
message:#"You triggered a custom action"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
PFQuery *query = [PFQuery queryWithClassName:#"ListItem"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
[query whereKey:#"listName" equalTo:[PFUser currentUser]];
listArray = [objects mutableCopy];
NSLog(#"I'm about to show you an array");
NSLog(#"%#", listArray);
}
else {
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
NSLog(#"This is a count of listArray");
NSLog(#"%#", listArray);
return [listArray count];
}
#end
What is the count of your Array at the end of - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section ?
Because if I look at the documentation of PFQuery, which I must say I've never used.
findObjectsInBackgroundWithBlock:
Finds objects asynchronously and calls the given block with the results.
- (void)findObjectsInBackgroundWithBlock:(PFArrayResultBlock)block
Parameters
block
The block to execute. The block should have the following argument signature:(NSArray objects, NSError error)
Discussion
Finds objects asynchronously and calls the given block with the results.
The description would suggest that at the end of your method the count of the Array is '0'. And only later when the block that you've past to the method run then you will have an array with data. And at that moment you would need to save you array and call [tableView reloadData] .
That would explain this :
Also, I figured that that was the problem because cellForRowAtIndexPath isn't being called.
This is probably the result of row in section being 0, because if your numberOfRowsInSection
method is called it means that your dataSource is properly set.
BUT there is an other much Bigger Problem with your code.
Because every time the table view wants to reload it's data, your making a fetch request, that will ask the table view to reload itself, which in turn will ask for a new query, that will ask the tableView to reload itself, which in turn... you get the picture.
You should make your query in viewDidLoad, viewWillAppear, or other place in the life cycle of your viewController that make sense for that query to be made, depending on the volatility of the data, how often the call need to be made etc.
And Also remember that updating the tableView must be done on the main thread. The documentation for PFQuery doesn't specify on which thread you'll be when the block will be running.
reload the table view after fetching data:
add this line:
listArray = [objects mutableCopy];
[tableView reloadData]
I managed to parse data from YouTube API on UITable view using AFNetworking but i cant figure out how to use
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
How do i pass the JSON data to the next view ?
Here is the link to the file: google drive
Here is my code
#import "KKViewController.h"
#import "AFNetworking.h"
#import "AFJSONRequestOperation.h"
#interface KKViewController ()
#end
#implementation KKViewController
#synthesize movies = _movies, count = _count;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.movies = [[NSArray alloc] init];
NSURL *url = [[NSURL alloc] initWithString:#"http://gdata.youtube.com/feeds/api/playlists/PL0l3xlkh7UnvLdr0Zz3XZZuP2tENy_qaP?v=2&alt=jsonc&max-results=50"];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
self.movies = [JSON valueForKeyPath:#"data.items.video"];
// NSLog(##, video)
//
self.count = [JSON valueForKeyPath:#"data.items.video.thumbnail"];
[self.activityIndicatorView stopAnimating];
[self.tableView setHidden:NO];
[self.tableView reloadData];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
NSLog(#"Request Failed with Error: %#, %#", error, error.userInfo);
}];
[operation start];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
if (self.movies && self.movies.count) {
return self.movies.count;
} else {
return 0;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellID = #"Cell Identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellID];
}
NSDictionary *movie = [self.movies objectAtIndex:indexPath.row];
NSDictionary *countt = [self.count objectAtIndex:indexPath.row];
cell.textLabel.text = [movie objectForKey:#"title"];
cell.detailTextLabel.text = [movie objectForKey:#"uploader"];
NSURL *url = [[NSURL alloc] initWithString:[countt objectForKey:#"hqDefault"]];
[cell.imageView setImageWithURL:url placeholderImage:[UIImage imageNamed:#"placeholder"]];
return cell;
}
I hope this sample code will help you to accomplish your needs easily.
Please ask if anything look ambiguous to you.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.leadsTableView deselectRowAtIndexPath:indexPath animated:YES];
id object = [[self.tableData objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
self.leadforLeadDetails = (Lead*)object;
self.selectedLeadID = self.leadforLeadDetails.ID;
[self performSegueWithIdentifier:#"openLeadDetails" sender:self];
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
//NSIndexPath *indexPath = [self.tableView2 indexPathForCell:sender];
//[self.tableView2 deselectRowAtIndexPath:indexPath animated:YES];
if ([segue.identifier isEqualToString:#"openLeadDetails"])
{
LeadsDetailsTableViewController *destViewController = segue.destinationViewController;
destViewController.dictLeadDetails = self.dictLeadDetails;
destViewController.leadID = self.leadforLeadDetails.ID;
destViewController.Name = self.leadforLeadDetails.Name;
destViewController.leadDetails.ID = self.leadforLeadDetails.ID;
destViewController.leadDetails.Name = self.leadforLeadDetails.Name;
}
}
You could either:
Define a segue in your storyboard's prototype for the cell in question and you don't have to write a didSelectRowAtIndexPath at all;
Have didSelectRowAtIndexPath do a performSegueWithIdentifier (giving it the unique string "storyboard identifier" that you set up for your segue in the storyboard;
You can then write a prepareSegue that would look at the table's indexPathForSelectedRow to identify what row was selected. You can then grab the appropriate information from your app's model and set the appropriate property in the destinationViewController.
You could also have didSelectRowAtIndexPath do an instantiateViewControllerWithIdentifier set the property, and then do the appropriate pushViewController or presentViewController, but I personally prefer the above techniques that leverage the segues you've defined in your storyboard.
I'm trying to reload a UITableView when the row of a different UITableView's row is selected. One of the problems I'm having is that both the UITableView's are in the same view. I would like a selection in Table1 to change the NSMutableArray that's used to populate Table2. And then reload the table.
At the moment it works fine, but only when the app re-lauches (or the view is popped off the stack and then re-visited) and viewWillAppear is called again
Here's my code:
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:NO];
[self.navigationController setNavigationBarHidden:YES animated:NO];
self.navigationController.toolbarHidden = YES;
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
// getting an NSString
selectedTableString = [prefs stringForKey:#"selectedTableString"];
if ([selectedTableString isEqualToString:#"Italy"]) {
jsonStringCountry = #"http://****/v1/public/cities?country=it";
}
else if ([selectedTableString isEqualToString:#"Spain"]) {
jsonStringCountry = #"http://****/v1/public/cities?country=es";
}
else if ([selectedTableString isEqualToString:#"UK"]) {
jsonStringCountry = #"http://****/v1/public/cities?country=uk";
}
else if ([selectedTableString isEqualToString:#"Brazil"]) {
jsonStringCountry = #"http://****/v1/public/cities?country=br";
}
NSLog(#"from two t selectedTableString %#",selectedTableString);
// Download the yoodeal JSON
NSString *jsonString = [NSString stringWithContentsOfURL:[NSURL URLWithString:jsonStringCountry] encoding:NSStringEncodingConversionAllowLossy|NSUTF8StringEncoding error:nil];
NSLog(#"jsonStringCountry is %#", jsonStringCountry);
NSMutableArray *itemsTMP = [[NSMutableArray alloc] init];
// Create parser for the yoodeal api
SBJSON *parser = [[SBJSON alloc] init];
NSDictionary *results = [parser objectWithString:jsonString error:nil];
itemsTMP = [results objectForKey:#"results"];
self.displayItems = [itemsTMP copy];
}
My UITableView methods:
- (int)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [displayItems count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MainCell"];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MainCell"];
}
// Get item from tableData
NSDictionary *item = (NSDictionary *)[displayItems objectAtIndex:indexPath.row];
cell.textLabel.text = [item objectForKey:#"name"];
[cell.textLabel setFont:[UIFont fontWithName: #"Asap-Bold" size: 14.0f]];
return cell;
}
You'll need to use the delegate method of UITablveView. The method is:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
This methods gets called when you click on the row of UITableView. Use this in following manner:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(tableView == Table1)
{
//do the changes in array you want to do.
[table2 reloadData];
}
else
{
//do the changes in array you want to do.
[table1 reloadData];
}
}
Create outlet for the table view
[self.yourTableView reloadData];
You should create a property of the UITableView called secondTableView and then use [secondTableView reloadData].
Use [tablename reloadData]; onclick.
When you are updating tableview contents, it will not refresh the view. You can only see changes once the view controller is reloaded.
For updating the table instantly you need to call the above code
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 11 years ago.
i am trying to devlope one RSSFeed application from http://www.raywenderlich.com/2636/how-to-make-a-simple-rss-reader-iphone-app-tutorial. everything was going well till this error occurs. i have checked everything in tutorial code but couldn't find anything. i have copied the code as it is. i have stuck here & wanted to get rid off it so i can go further & work get done. i am putting the piece of code below. please anyone can help me with it.
thnx in advance..
// RootViewController.m
// RSSFun
#import "GDataXMLNode.h"
#import "GDataXMLElement-Extras.h"
#import "ASIHTTPRequest.h"
#import "RSSEntry.h"
#import "RootViewController.h"
#implementation RootViewController
#synthesize feeds = _feeds;
#synthesize queue = _queue;
#synthesize allEntries = _allEntries;
- (void)refresh {
for (NSString *feed in _feeds) {
NSURL *url = [NSURL URLWithString:feed];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[_queue addOperation:request];
}
}
- (void)addRows {
RSSEntry *entry1 = [[[RSSEntry alloc] initWithBlogTitle:#"1"
articleTitle:#"1"
articleUrl:#"1"
articleDate:[NSDate date]] autorelease];
RSSEntry *entry2 = [[[RSSEntry alloc] initWithBlogTitle:#"2"
articleTitle:#"2"
articleUrl:#"2"
articleDate:[NSDate date]] autorelease];
RSSEntry *entry3 = [[[RSSEntry alloc] initWithBlogTitle:#"3"
articleTitle:#"3"
articleUrl:#"3"
articleDate:[NSDate date]] autorelease];
[_allEntries insertObject:entry1 atIndex:0];
[_allEntries insertObject:entry2 atIndex:0];
[_allEntries insertObject:entry3 atIndex:0];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Feeds";
self.allEntries = [NSMutableArray array];
self.queue = [[[NSOperationQueue alloc] init] autorelease];
self.feeds = [NSArray arrayWithObjects:#"http://feeds.feedburner.com/RayWenderlich",
#"http://feeds.feedburner.com/vmwstudios",
#"http://idtypealittlefaster.blogspot.com/feeds/posts/default",
#"http://www.71squared.com/feed/",
#"http://cocoawithlove.com/feeds/posts/default",
#"http://feeds2.feedburner.com/brandontreb",
#"http://feeds.feedburner.com/CoryWilesBlog",
#"http://geekanddad.wordpress.com/feed/",
#"http://iphonedevelopment.blogspot.com/feeds/posts/default",
#"http://karnakgames.com/wp/feed/",
#"http://kwigbo.com/rss",
#"http://shawnsbits.com/feed/",
#"http://pocketcyclone.com/feed/",
#"http://www.alexcurylo.com/blog/feed/",
#"http://feeds.feedburner.com/maniacdev",
#"http://feeds.feedburner.com/macindie",
nil];
[self refresh];
}
/*
- (void)viewDidLoad {
[super viewDidLoad];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
*/
/*
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
*/
/*
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
*/
/*
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
}
*/
/*
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
}
*/
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release anything that can be recreated in viewDidLoad or on demand.
// e.g. self.myOutlet = nil;
}
- (void)requestFinished:(ASIHTTPRequest *)request {
//Error occurs here
[_queue addOperationWithBlock:^
{
NSError *error;
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:[request responseData]
options:0 error:&error];
if (doc == nil) {
NSLog(#"Failed to parse %#", request.url);
} else {
NSMutableArray *entries = [NSMutableArray array];
[self parseFeed:doc.rootElement entries:entries];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
for (RSSEntry *entry in entries) {
int insertIdx = 0;
[_allEntries insertObject:entry atIndex:insertIdx];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:insertIdx inSection:0]]
withRowAnimation:UITableViewRowAnimationRight];
}
}];
}
}];
}
- (void)requestFailed:(ASIHTTPRequest *)request {
NSError *error = [request error];
NSLog(#"Error: %#", error);
}
- (void)parseFeed:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries {
if ([rootElement.name compare:#"rss"] == NSOrderedSame) {
[self parseRss:rootElement entries:entries];
} else if ([rootElement.name compare:#"feed"] == NSOrderedSame) {
[self parseAtom:rootElement entries:entries];
} else {
NSLog(#"Unsupported root element: %#", rootElement.name);
}
}
- (void)parseRss:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries {
NSArray *channels = [rootElement elementsForName:#"channel"];
for (GDataXMLElement *channel in channels) {
NSString *blogTitle = [channel valueForChild:#"title"];
NSArray *items = [channel elementsForName:#"item"];
for (GDataXMLElement *item in items) {
NSString *articleTitle = [item valueForChild:#"title"];
NSString *articleUrl = [item valueForChild:#"link"];
NSString *articleDateString = [item valueForChild:#"pubDate"];
NSDate *articleDate = nil;
RSSEntry *entry = [[[RSSEntry alloc] initWithBlogTitle:blogTitle
articleTitle:articleTitle
articleUrl:articleUrl
articleDate:articleDate] autorelease];
[entries addObject:entry];
}
}
}
- (void)parseAtom:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries {
NSString *blogTitle = [rootElement valueForChild:#"title"];
NSArray *items = [rootElement elementsForName:#"entry"];
for (GDataXMLElement *item in items) {
NSString *articleTitle = [item valueForChild:#"title"];
NSString *articleUrl = nil;
NSArray *links = [item elementsForName:#"link"];
for(GDataXMLElement *link in links) {
NSString *rel = [[link attributeForName:#"rel"] stringValue];
NSString *type = [[link attributeForName:#"type"] stringValue];
if ([rel compare:#"alternate"] == NSOrderedSame &&
[type compare:#"text/html"] == NSOrderedSame) {
articleUrl = [[link attributeForName:#"href"] stringValue];
}
}
NSString *articleDateString = [item valueForChild:#"updated"];
NSDate *articleDate = nil;
RSSEntry *entry = [[[RSSEntry alloc] initWithBlogTitle:blogTitle
articleTitle:articleTitle
articleUrl:articleUrl
articleDate:articleDate] autorelease];
[entries addObject:entry];
}
}
#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 [_allEntries 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:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
NSDateFormatter * dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *articleDateString = [dateFormatter stringFromDate:entry.articleDate];
cell.textLabel.text = entry.articleTitle;
cell.detailTextLabel.text = [NSString stringWithFormat:#"%# - %#", articleDateString, entry.blogTitle];
return cell;
}
/*
// Override to support row selection in the table view.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic may go here -- for example, create and push another view controller.
// AnotherViewController *anotherViewController = [[AnotherViewController alloc] initWithNibName:#"AnotherView" bundle:nil];
// [self.navigationController pushViewController:anotherViewController animated:YES];
// [anotherViewController release];
}
*/
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source.
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
- (void)dealloc {
[super dealloc];
[_allEntries release];
_allEntries = nil;
[_queue release];
_queue = nil;
[_feeds release];
_feeds = nil;
}
#end
Just before your dealloc method you have a spurious */ which needs removing.
enter code hereRight at teh end of your file you have the following:
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
That last end comment block */ should be removed as it has no start block. leaving:
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
What did I do wrong? I just modified the Navigation Based application code a bit to read and display a JSON string. It crashes when I scroll up the list with the message Objc_msgSend and points at this as the problem: cell.textLabel.text=[[locations objectAtIndex: storyIndex] objectForKey: #"title"];
#import "RootViewController.h"
#import "JSON.h"
#implementation RootViewController
#synthesize locations;
- (NSString *)stringWithUrl:(NSURL *)url
{
// Construct a String around the Data from the response
return [[NSString alloc] initWithContentsOfURL:url];
}
-(void)jsonLoad {
NSURL *URL = [NSURL URLWithString:#"http://bombaytokyo.com/whrru/jsonexample.html"];
NSString *jsonstring = [self stringWithUrl:URL];
NSLog(jsonstring);
locations = [jsonstring JSONValue];
[jsonstring release];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
[self jsonLoad];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
[locations release];
}
- (void)viewDidUnload {
// Release anything that can be recreated in viewDidLoad or on demand.
// e.g. self.myOutlet = nil;
}
#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 0;
return [locations 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.
int storyIndex = [indexPath indexAtPosition: [indexPath length] - 1];
NSLog(#"Index Path: %i",indexPath);
//NSLog(title);
cell.textLabel.text=[[locations objectAtIndex: storyIndex] objectForKey: #"title"];
return cell;
}
- (void)dealloc {
[super dealloc];
}
#end
0 based arrays, id length is 0 the 0 - 1 = -1 this will obviously cause an exception.
[indexPath indexAtPosition: [indexPath length] - 1]
change to
[indexPath indexAtPosition: [indexPath length]]
and are you sure you dont want indexPath.row. it looks like you are just returning the length each time.
solution:
self.locations = [jsonstring JSONValue];
Thanks for all the suggestions.