iphone slow navigation due to data load - iphone

I'm newbie to objective-c . My problem is slow navigation between controllers.
When I jump from one controller to another it's really slow, because it gets data from the service, parse it and then display it. All this takes around 4-5 secs.
Now I've put all this data fetching in loadView of my DetailController. Is there anyway that I show the controller first and then display the data. Because as of now, when I select a row on my root controller, it shows activity and stays on root controller and then it navigates to the DetailController.
So it loads the data first and then displays it. Is there anyway that I can reverse this process, show the controller first and then display it..
this is what I'm doing
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DataCollection *collection = [DataCollection sharedObject];
Product *tempProduct = [[collection popularProducts] objectAtIndex:row] ;
ProductDetailViewController *tempProductDetail = [[ProductDetailViewController alloc] init];
tempProductDetail.homeViewProduct = tempProduct;
[tempProductDetail release];
}
and then the Detail Controller
- (void)loadView {
[super loadView];
// here's all the data loading and parsing ... which takes time
}
//Here's the method for downloading the data, I'm using a REST service to get all the data.
- (void) getProductData:(NSString*)productId{
NSMutableString *specificURL = [[NSMutableString alloc] initWithString:#"GetProductPage?id="];
[specificURL appendFormat:#"%#",productId];
[specificURL appendFormat:#"&dataSources=&accountId=&companyId=&version=1&cultureCode=sv&currencyId=2&format=json"];
NSDictionary *serverCategories = [[NSDictionary alloc] initWithDictionary:[appRequestController proceesRequest:specificURL]];
NSArray *categories = [[[serverCategories objectForKey:#"DataSources"] objectAtIndex:0] objectForKey:#"Items"];
[serverCategories release];
if ([[productsArray objectAtIndex:j] objectForKey:#"Name"] != [NSNull null]) {
[product setProductName:[[productsArray objectAtIndex:j] objectForKey:#"Name"]];
}
else {
[product setProductName:#""];
}
if ([[productsArray objectAtIndex:j] objectForKey:#"ThumbnailImage"] != [NSNull null]) {
[product setProductImage:[[productsArray objectAtIndex:j] objectForKey:#"ThumbnailImage"]];
}
else {
[product setProductImage:#""];
}
if ([[productsArray objectAtIndex:j] objectForKey:#"Price"] != [NSNull null]) {
[product setProductPrice:[[productsArray objectAtIndex:j] objectForKey:#"Price"]];
}
else {
[product setProductPrice:#""];
}
[[collection popularProducts] addObject:product];
[product release];
}
I've copy pasted junks of the code so that you can get an idea how I'm getting the data. Below is the code for cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *MyIdentifier = #"mainMenuIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
[cell setSelectedBackgroundView:[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"highlightstrip.png"]]];
}
UILabel *productNameLbl = [[UILabel alloc] initWithFrame:CGRectMake(90, 8, 200,10)];
[productNameLbl setText:[NSString stringWithString:[[[[DataCollection sharedObject] popularProducts]objectAtIndex:indexPath.row] productName]]];
[productNameLbl setFont:[UIFont boldSystemFontOfSize:12.0]];
[cell addSubview:productNameLbl];
[productNameLbl release];
UILabel *productSubLbl = [[UILabel alloc] initWithFrame:CGRectMake(90, 22, 190,40)];
[productSubLbl setText:[NSString stringWithString:[[[[DataCollection sharedObject] popularProducts]objectAtIndex:indexPath.row] productSubHeader]]];
[productSubLbl setTextColor:[UIColor colorWithRed:102.0/255.0 green:102.0/255.0 blue:102/255.0 alpha:1.0]];
productSubLbl.lineBreakMode = UILineBreakModeWordWrap;
productSubLbl.numberOfLines = 3;
[productSubLbl setFont:[UIFont fontWithName:#"Arial" size:10]];
[cell addSubview:productSubLbl];
[productSubLbl release];
NSMutableString *url = [[NSMutableString alloc] initWithString:#""];
NSString *baseImageURL = #"http://samplesite.com/";
NSString *imagePath = [NSString stringWithString:[[[[DataCollection sharedObject] popularProducts]objectAtIndex:indexPath.row] productImage]];
[url appendString:baseImageURL];
[url appendString:imagePath];
NSURL *imageURL = [NSURL URLWithString:url];
NSData *data = [NSData dataWithContentsOfURL:imageURL];
UIImage *img = [[UIImage alloc] initWithData:data cache:NO];
UIImageView *imageView = [[UIImageView alloc] initWithImage:img];
[imageView setFrame:CGRectMake(10, 10, 70, 70)];
[cell addSubview:imageView];
[imageView release];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}

Pass the url or product id to the detail view. Inside the viewDidLoad of the ProductDetail, create a background thread to retrieve your data. When you background thread finish, it will notify your ProductDetail controller with the detail. At that time, you update your ProductDetailView.
To get your data on a background thread you can use
NSThread
NSOperation

Pass the row into your ProductDetailViewController, and do the fetch in it's viewDidLoad method. You might also want to show a spinner (UIActivityIndicator), and you definitely should read up on background threads.

To make view available to user and loading data after some time you can use NSTimer.
Just have a NSTimer method which will be called in viewDidLoad method as
[NSTimer scheduledTimerWithTimeInterval:<#(NSTimeInterval)ti#> target:<#(id)aTarget#> selector:<#(SEL)aSelector#> userInfo:<#(id)userInfo#> repeats:<#(BOOL)yesOrNo#>]
put some time interval which will be calling your loading method after that.
Hope this helps.

Related

Application shows low memory warning and crashes while loading images?

I am using following code for loading images from server using following code.When i scroll UITableView application crashes.
AsynchrohousImageView class .m file
- (void)dealloc {
[connection cancel]; //in case the URL is still downloading
[connection release];
[data release];
[_imageView release];
[_activityIndicator release];
[super dealloc];
}
- (void)loadImageFromURL:(NSURL*)url
defaultImageName:(NSString *)defaultImageName
showDefaultImage:(BOOL)defaultImageIsShown
showActivityIndicator:(BOOL)activityIndicatorIsShown
activityIndicatorRect:(CGRect)activityIndicatorRect
activityIndicatorStyle:(UIActivityIndicatorViewStyle)activityIndicatorStyle {
if (connection!=nil) { [connection release]; } if (data!=nil) { [data release]; }
if ([[self subviews] count]>0) {
[[[self subviews] objectAtIndex:0] removeFromSuperview]; // }
if (defaultImageIsShown) {
self.imageView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:defaultImageName]] autorelease];
} else {
self.imageView = [[[UIImageView alloc] init] autorelease];
}
[self addSubview:_imageView];
_imageView.frame = self.bounds;
[_imageView setNeedsLayout];
[self setNeedsLayout];
if (activityIndicatorIsShown) {
self.activityIndicator = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:activityIndicatorStyle] autorelease];
[self addSubview:_activityIndicator];
_activityIndicator.frame = activityIndicatorRect;
_activityIndicator.center = CGPointMake(_imageView.frame.size.width/2, _imageView.frame.size.height/2);
[_activityIndicator setHidesWhenStopped:YES];
[_activityIndicator startAnimating];
}
NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)incrementalData {
if (data==nil) { data = [[NSMutableData alloc] initWithCapacity:2048]; }
[data appendData:incrementalData];
}
- (void)connectionDidFinishLoading:(NSURLConnection*)theConnection {
[connection release];
connection=nil;
_imageView.image = [UIImage imageWithData:data];
if (_activityIndicator) {
[_activityIndicator stopAnimating];
}
[data release]; data=nil;
}
- (UIImage*) image {
UIImageView* iv = [[self subviews] objectAtIndex:0];
return [iv image];
}
In ViewController Class Which loads image
- (UITableViewCell *)tableView:(UITableView *)tV cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *reuseIdentifier =#"CellIdentifier";
ListCell *cell = (ListCell *)[tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (cell==nil) {
cell = [[ListCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
NSMutableDictionary *dicResult = [arrResults objectAtIndex:indexPath.row];
NSURL *url=[NSURL URLWithString:[dicResult objectForKey:#"Image"]];
AsynchronousImageView *asyncImageView = [[AsynchronousImageView alloc] initWithFrame:CGRectMake(5, 10,80,80)];
[asyncImageView loadImageFromURL:url
defaultImageName:#"DefaultImage.png"
showDefaultImage:NO
showActivityIndicator:YES
activityIndicatorRect:CGRectMake(5, 10,30,30)
activityIndicatorStyle:UIActivityIndicatorViewStyleGray]; // load our image with URL asynchronously
[cell.contentView addSubview:asyncImageView];
// cell.imgLocationView.image = [UIImage imageNamed:[dicResult valueForKey:#"Image"]];
[asyncImageView release];
}
if([arrResults count]==1)
{
UITableViewCell *cell1=[tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if(cell1==nil)
cell1=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier] autorelease];
NSMutableDictionary *dicResult = [arrResults objectAtIndex:0];
cell1.textLabel.text=[dicResult valueForKey:#"NoResults"];
return cell1;
}
else
{
NSMutableDictionary *dicResult = [arrResults objectAtIndex:indexPath.row];
NSString *title = [NSString stringWithFormat:#"%# Bedrooms-%#", [dicResult valueForKey:KEY_NUMBER_OF_BEDROOMS],[dicResult valueForKey:KEY_PROPERTY_TYPE]];
NSString *strAddress = [dicResult valueForKey:KEY_DISPLAY_NAME];
NSString *address = [strAddress stringByReplacingOccurrencesOfString:#", " withString:#"\n"];
NSString *price = [dicResult valueForKey:KEY_PRICE];
NSString *distance = [dicResult valueForKey:KEY_DISTANCE];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.lblTitle.text = title;
cell.lblAddress.text = address;
if ([price length]>0) {
cell.lblPrice.text = [NSString stringWithFormat:#"£%#",price];
}else{
cell.lblPrice.text = #"";
}
if ([distance length]>0) {
cell.lblmiles.text = [NSString stringWithFormat:#"%.2f miles",[distance floatValue]];
}else{
cell.lblmiles.text = #"";
}
}
return cell;
}
How can i resolve this?
I have attached heapshot analysis screen shot of it.Here non Object consumes so much of memory what is that?
this is the error:
NSString *reuseIdentifier = [NSString stringWithFormat:#"%d",indexPath.row];
it seems you are NOT reusing cells, but creating a new cell for every row of your table!!!
this way if you need to see 100 or 1000 rows, you create/allocate 100 or 1000 object cells.
that's not the right use of a UITableView.
the "magic" of UITableView is that it reuse cells, and it just creates and allocates just the minor number of cells needed...
e.g. consider you have a vertical spaces of 480 pixels for your tables, and your cells are 100 pixel height, then you just need 5 cells for time, no need to create 1000 cells, you can see just 5 cells at time...
so the magic is to reuse an already allocated cell when you scroll it up and it goes out of screen, and to reset it's contents (images and text) and to use it for the new call that user is going to see down...
While cell reuse is not the problem, leaking cells is:
cell = [[ListCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
You forgot to autorelease this, so you're leaking cells very quickly. You did remember to autorelease cell1.

ASIHTTPRequest is not updating the DownloadProgress Delegate

I am using ASIHTTPRequest to download a file locally to the iDevice.
My download code is as follows
ASIHTTPRequest *download = [ASIHTTPRequest requestWithURL: videoUrl];
[download setCompletionBlock:^{
NSLog(#"Download Success");
// other code
}];
[download setFailedBlock:^{
NSLog(#"Download Failed");
// other code
}];
[download setDownloadProgressDelegate: [item progressDelegate]];
[download startAsynchronous];
NSLog(#"Start Download of %#", [item name]);
The object item holds a reference to a UIProgressView It is show on the screen but never updated.
In an attempt to debug, I subclassed UIProgressView and added the following log
- (void)setProgress:(float)newProgress {
NSLog(#"Current Progress : %f", newProgress);
[super setProgress: newProgress];
}
My Console now shows the progress going from 0.0 to 1.0 over ~50 iterations (nice!) but the uiProgressView doesnt change and at the end the NSLog show 0.5 the default setting for the progress view.
Anyone have an Idea what is happening?
EDIT
UIProgressView is accessed with this
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath: indexPath];
id progressView = [cell viewWithTag:VideoDetailProgressView];
[VideoDownloadManager queueDownloadOfVideo:video progressDelegate: progressView];
}
I have stepped through and watched it appears to keep the correct reference to the UIProgressView throughout
Edit
TableView Methods
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *detailCellIdentifier = #"VideoDetailCell";
static NSString *categoryCellIdentifier = #"VideoCategoryCell";
UITableViewCell *cell = nil;
bool isCategorical = [[self.videoList objectAtIndex: indexPath.row] objectForKey:#"parentName"];
if(isCategorical)
{
cell = [tableView dequeueReusableCellWithIdentifier:categoryCellIdentifier];
}
else
{
cell = [tableView dequeueReusableCellWithIdentifier:detailCellIdentifier];
}
if (cell == nil && !isCategorical) {
[[NSBundle mainBundle] loadNibNamed:#"VideoDetailCell" owner:self options:nil];
cell = self.videoDetailCell;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(5.0, 10.0, 46.0, 46.0)];
[cell addSubview:imageView];
imageView.hidden = !self.canEdit;
imageView.tag = VideoDetailsFavoriteButton;
[imageView release];
self.videoDetailCell = nil;
}
else if(cell == nil && isCategorical)
{
//Different cell
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:categoryCellIdentifier] autorelease];
}
[cell setBackgroundColor:[UIColor clearColor]];
return cell;
}
// Display customization
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *object = [self.videoList objectAtIndex:indexPath.row];
bool isCategorical = [[self.videoList objectAtIndex: indexPath.row] objectForKey:#"parentName"];
if(isCategorical) {
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.text = [object objectForKey:#"name"];
NSUInteger videoCount = [[Videos sharedVideos] countById: [object objectForKey:#"name"]];
cell.detailTextLabel.textColor = [UIColor whiteColor];
cell.detailTextLabel.text = [NSString stringWithFormat: #"%d videos", videoCount];
}
else
{
[[cell viewWithTag:VideoDetailCellTitle] setValue:[object objectForKey:#"name"] forKey:#"text"];
[[cell viewWithTag:VideoDetailCellSubtitle] setValue:[object objectForKey:#"dateAdded"] forKey:#"text"];
[[cell viewWithTag:VideoDetailCellDuration] setValue:[object objectForKey:#"duration"] forKey:#"text"];
UIHTTPImageView *asyncImage = (UIHTTPImageView *)[cell viewWithTag:VideoDetailCellImage];
NSURL *thumbUrl = [NSURL URLWithString:[NSString stringWithFormat: #"%#%#", kRootUrlPath, [object objectForKey:#"image"]]];
[asyncImage setImageWithURL:thumbUrl placeholderImage: [UIImage imageNamed: kLoadingImage]];
asyncImage.clipsToBounds = YES;
UIImageView *editButton = (UIImageView *)[cell viewWithTag:VideoDetailsFavoriteButton];
if ([VideoDownloadManager isQueued: [object objectForKey: #"name"]]) {
[[cell viewWithTag:VideoDetailCellSubtitle] setHidden:YES];
[[cell viewWithTag:VideoDetailProgressView] setHidden:NO];
} else {
[[cell viewWithTag:VideoDetailCellSubtitle] setHidden:NO];
[[cell viewWithTag:VideoDetailProgressView] setHidden:YES];
}
if ([VideoDownloadManager isFavorites: [object objectForKey: #"name"]] || [VideoDownloadManager isQueued: [object objectForKey: #"name"]]) {
editButton.image = [UIImage imageNamed: kFavoritesHighlighted];
} else {
editButton.image = [UIImage imageNamed: kFavoritesEmpty];
}
}
}
Can you check if the update is made in the main thread? (it should be the case if you're using the latest version of ASIHTTPRequest)
NSLog(#"Current Progress : %f (main thread=%d)", newProgress, [NSThread isMainThread]);
If it doesn't help, can you show the code that is using the UIProgressView in the view?
Thanks for everyones help. You guys guided me to then answer. My cell was not correctly being assigned a reuseIdentifier
this was causing the whole issue.

iPhone and Twitter API OAuth Consumer Keys and Secrets

I have a issue while loading my data from Twitter. The method I posted below works for about 5-10 minutes then it freezes up my consumer keys....
I know it is the keys because I have the app already installed on the device working then I will make changes and run on the simulator and it affects the device as well. This last for about 30 minutes then the keys seem to refresh themselves and work without any changes to the actual code. Sometimes I will just go in Twitter Dev were my application is and reset the keys and replace the keys in my code and that works for about 10 minutes then the same thing happens!
Here is the code I am using to call out to twitter OAuth and receive the objects for my UITableView.
- (void)viewDidAppear:(BOOL)animated
{
if(_engine) return;
_engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];
_engine.consumerKey = #"key";
_engine.consumerSecret = #"key";
UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine: _engine delegate: self];
if (controller)
[self presentModalViewController: controller animated: YES];
else
{
userAvatar.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://a2.twimg.com/profile_images/1361674958/Wintboard_200px.png" ]]];
tweets = [[NSMutableArray alloc] init];
authors = [[NSMutableArray alloc] init];
avatarsURL =[[NSMutableArray alloc] init];
friendsCount = [[NSMutableArray alloc] init];
followerCount = [[NSMutableArray alloc] init];
retweetCount = [[NSMutableArray alloc] init];
//retweetCount = [[NSMutableArray alloc] init];
[self updateStream:nil];
[progressView.view removeFromSuperview];
}
}
#pragma mark IBActions
-(IBAction)updateStream:(id)sender
{
// [_engine sendUpdate:[textfield text]];
[_engine getFollowedTimelineSinceID:0 startingAtPage:0 count:100];
//[_twitter getFollowedTimelineSinceID:0 startingAtPage:0 count:0];
NSString *path = [[NSBundle mainBundle] pathForResource:#"unlock" ofType:#"caf"];
AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
}
-(IBAction)tweet:(id)sender
{
[_engine sendUpdate:[textfield text]];
[self updateStream:nil];
if (textfield isFirstResponder])
{
textfield.text = #"";
[textfield resignFirstResponder];
}
}
-(BOOL)textFieldShouldClear:(UITextField*)textfield
{
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
// the user pressed the "Done" button, so dismiss the keyboard
[textField resignFirstResponder];
return YES;
}
// Return YES for supported orientations
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation
{
return YES;
}
#pragma mark UITableViewDataSource Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// [_engine sendUpdate:[textfield text]];
[_engine getFollowedTimelineSinceID:0 startingAtPage:0 count:100];
int count = [tweets count];
int count2 = [authors count];
int count3 = [avatarsURL count];
//Return just enough cells to fill the screen during loading ....
if (count == 0)
count = MyCustomRowCount;
return count = 100;
return count2 = 100;
return count3 = 100;
// return count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier] autorelease];
}
/*
//Here it adds a nice shadow to the table view but will crash on rotation and send a wird dump
tableView.layer.shadowColor = [[UIColor blackColor] CGColor];
tableView.layer.shadowOffset = CGSizeMake(1.0f, 1.0f);
tableView.layer.shadowRadius = 8.0f;
tableView.layer.shadowOpacity = 1.0f;
*/
[cell.textLabel setNumberOfLines:1];
[cell.textLabel setText:[(Tweet*)[authors objectAtIndex:indexPath.row] author]];
[cell.detailTextLabel setText:[(Tweet*)[tweets objectAtIndex:indexPath.row] tweet]];
[cell.detailTextLabel setNumberOfLines:10];
[cell.textLabel setTextColor:[UIColor darkGrayColor]];
[cell.textLabel setShadowColor:[UIColor whiteColor]];
[cell.textLabel setShadowOffset:CGSizeMake(0.5, 0.5)];
[cell.detailTextLabel setTextColor:[UIColor blackColor]];
//[cell.detailTextLabel setText:[(Tweet*)[retweetCount objectAtIndex:indexPath.row] reTweetCount]];
[cell.textLabel setUserInteractionEnabled:YES];
[cell.contentView setMultipleTouchEnabled:YES];
// Here we use the new provided setImageWithURL: method to load the web image with SDWebImageManager
[cell.imageView setImageWithURL:[NSURL URLWithString:[(Tweet*)[avatarsURL objectAtIndex:indexPath.row]avatarURL]]
placeholderImage:[UIImage imageNamed:#"avatar.png"]];
//add gradient to cell
UIImage *gradient = [UIImage imageNamed:#"gradientcell2.png"];
UIImageView *cellimage = [[UIImageView alloc] initWithImage:gradient];
cellimage.contentMode = UIViewContentModeScaleToFill;
cell.backgroundView = cellimage;
[cellimage release];
UIImage *selectedGradient = [UIImage imageNamed:#"selectedcell.png"];
UIImageView *selectedCell = [[UIImageView alloc] initWithImage:selectedGradient];
selectedCell.contentMode = UIViewContentModeScaleToFill;
cell.selectedBackgroundView = selectedCell;
[tableView setBackgroundColor:[UIColor clearColor]];
return cell;
}
Yes Sorry I should have came back and answered this!
First make sure your requests are not going over Twitters API request Limit, I was simply while reloading my table view.
After Fixing that mistake I the proceeded to reset my keys wrote a request to Twitter API to use xAuth "it only takes a few days to be accepted" then I have not had any issues since.
I did not use my keys until I received the letter from Twitter saying I was accepted and I have not had any issues since.
I hope this helps because I know how frustrating that can become !
Good Luck!

UITableView ObjectAtIndex

I'm developing an iPhone app that is a tabViewController with one of the tabs including a tableView. Objects in the table can be touched to go to a splash screen with information for that specific object.
Here's how I set up the array tableView:
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//each table view cell has its own identifier.
static NSString *cellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier] autorelease];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [sitesArray objectAtIndex:row];
cell.imageView.image = [imagesArray objectAtIndex:row];
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
return cell;
}
- (void)viewDidLoad {
NSArray *pageHolder = [[NSArray alloc] initWithObjects:#"CSLP", #"NSLS", #"LSPA", #"SIOP", #"Transfer", nil];
self.pages = pageHolder;
[pageHolder release];
NSArray *sites = [[NSArray alloc] initWithObjects:#"CSLP", #"NSLS", #"LSPA", #"SIOP", #"Transfer Vision Program ", nil];
self.sitesArray = sites;
UIImage *cslp = [UIImage imageNamed:#"CSLP LOGO.png"];
UIImage *nsls = [UIImage imageNamed:#"NSLS LOGO.png"];
UIImage *lspa = [UIImage imageNamed:#"LSPA LOGO.png"];
UIImage *siop = [UIImage imageNamed:#"SIOP LOGO.png"];
UIImage *transfer = [UIImage imageNamed:#"TRANSFER LOGO.png"];
NSArray *images = [[NSArray alloc] initWithObjects: cslp, nsls, lspa, siop, transfer, nil];
[sites release];
self.imagesArray = images;
UIButton* modalViewButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[modalViewButton addTarget:self action:#selector(modalViewAction:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *modalBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:modalViewButton];
self.navigationItem.rightBarButtonItem = modalBarButtonItem;
[modalBarButtonItem release];
[self.table reloadData];
}
And here's my didSelectRowAtIndexPath method
-(void) tableView:(UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath
{
NSInteger row = [indexPath row];
NSMutableDictionary *rowData = [table objectAtIndex:indexPath.row];
UIViewController *targetViewController = [rowData objectForKey:kViewControllerKey];
if (!targetViewController)
{
// The view controller has not been created yet, create it and set it to our menuList array
NSString *viewControllerName = [[pages objectAtIndex:indexPath.row] stringByAppendingString:#"ViewController"];
targetViewController = [[NSClassFromString(viewControllerName) alloc] initWithNibName:viewControllerName bundle:nil];
[rowData setValue:targetViewController forKey:kViewControllerKey];
[targetViewController release];
}
SSARC_App_2AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[delegate.orgsNavigationController pushNavigationItem:targetViewController animated:YES];
[delegate release];
}
The application crashes at the first call to objectAtIndex in the didSelectRowAtIndexPath method. The console states:
010-11-22 12:50:17.113 SSARC App
2[43470:207] -[UITableView
objectAtIndex:]: unrecognized selector
sent to instance 0x601e800 2010-11-22
12:50:17.116 SSARC App 2[43470:207]
* Terminating app due to uncaught exception
'NSInvalidArgumentException', reason:
'-[UITableView objectAtIndex:]:
unrecognized selector sent to instance
0x601e800'
* Call stack at first throw:
Now, I have a warning that says "UITableView may be unresponsive to ObjectAtIndex". I'm assuming this is the main issue here, however I'm unsure how to solve it. Interestingly enough I've searched for this issue everywhere, and cannot find it anywhere, so I'm curious to know if anyone has run into this problem and how to solve it. Any advice would be great. Let me know if you need more information.
I've been doing some coding on my own and I've gotten it to compile without any errors or warnings, but it still crashes. Currently this is what I have:
NSMutableDictionary *rowData = [self.menuList objectAtIndex:indexPath.row];
UIViewController *targetViewController = [rowData objectForKey:kViewControllerKey];
if (!targetViewController)
{
// The view controller has not been created yet, create it and set it to our menuList array
NSString *viewControllerName = [[pages objectAtIndex:indexPath.row] stringByAppendingString:#"ViewController"];
targetViewController = [[NSClassFromString(viewControllerName) alloc] init];//WithNibName:viewControllerName bundle:nil];
NSLog(#"targetViewController: %#", targetViewController);
[rowData setValue:targetViewController forKey:kViewControllerKey];
[targetViewController release];
}
SSARC_App_2AppDelegate *delegate = (SSARC_App_2AppDelegate*)[[UIApplication sharedApplication] delegate];
[[delegate orgsNavigationController] pushViewController:targetViewController animated:YES];
[delegate release];
delegate = nil;
The issue that the debugger reports is that 'viewControllerName' is 'Out of Scope'. I don't really understand what that means because when I use NSLog, viewControllerName is initialized. Does that mean it cannot find the class I'm referring to? Please let me know.
Assuming table is your UITableView, the call to [table objectAtIndex:indexPath.row] is completely nonsensical. It looks to me like you should be calling [pages objectAtIndex:indexPath.row] instead.
objectAtIndex should be called either for NSMutableArray Or NSArray. You cann't call it from UITableview Or CFDictionary Or CFString. So if you gets any warning Solve the warning first and then proceed further.

async images problem with threaded data

im having an issue with my tableviews and threaded data. in my app im downloading data in xml, including an image url which im then parsing to get the image for my tableviews.
im using the asyncimageview class (markj.net). if i thread the download of my xml, then realoadData the cells appear fine , appart form the images never load, until they are dequeued and reloaded, and i have no idea how to fix it.
help please.....
ok i managed to fix it using this
- (void)loadImagesForVisibleCells;
{
NSArray cells = [self.newsStories visibleCells];
[cells retain];
for (int i = 0; i < [cells count]; i++)
{
// Go through each cell in the array and call its loadContent method if it responds to it.
CGRect frame;
frame.size.width=75; frame.size.height=75;
frame.origin.x=0; frame.origin.y=0;
AsyncImageView asyncImage = [[[AsyncImageView alloc]
initWithFrame:frame] autorelease];
//AsyncImageView *asyncImage = (AsyncImageView *)[[cells objectAtIndex: i] retain];
//*flickrCell = (FlickrCell *)[[cells objectAtIndex: i] retain];
NewcastleStories *aStory = [stories objectAtIndex:i];
//AsyncImageView* asyncImage = [[AsyncImageView alloc]init];
[asyncImage emptyImages];
NSURL* url =[NSURL URLWithString:aStory.picture];
[asyncImage loadImageFromURL:url];
//[cells objectAtIndex:i])
static NSString *CellIdentifier = #"ImageCell";
UITableViewCell *cell = [newsStories dequeueReusableCellWithIdentifier:CellIdentifier];
[cell.contentView addSubview:asyncImage];
[[self newsStories]setNeedsLayout];
[[self newsStories] setNeedsDisplay];
//[self dataLoaded];
//[asyncImage loadImage];
//[flickrCell release];
//flickrCell = nil;
}
[cells release];
}
but it has to be called in the main thread using
[self performSelectorOnMainThread:#selector(loadImagesForVisibleCells) withObject:nil waitUntilDone:YES];