views:

405

answers:

1

I really can't get this to work, basically when my JSON feeds loads I want the indicator to show, then hide when it's stopped.

It loads top level menu items 1st "Publishing, Broadcasting, Marketing Services", then when Broadcasting is selected it loads a feed using the JSON framework hosted on Google. Round this load I call startIndicator and stopIndicator using the NSThread. Have I missed something?

@implementation GeneralNewsTableViewController

@synthesize dataList;
@synthesize generalNewsDetailViewController;
@synthesize atLevel;


-(void) startIndicator
{
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc ] init ];
 [(UIActivityIndicatorView *)[self navigationItem].rightBarButtonItem.customView startAnimating];
 [pool release];

}

-(void) stopIndicator
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc ] init ];
 [(UIActivityIndicatorView *)[self navigationItem].rightBarButtonItem.customView stopAnimating];
 [pool release];

}

- (void)viewDidLoad {

 NSMutableArray *checker = self.dataList;

 if(checker == nil)
 {
  self.title = NSLocalizedString(@"General1",@"General News");

  NSMutableArray *array = [[NSArray alloc] initWithObjects:@"Publishing", @"Broadcasting",@"Marketing Services",nil];
  self.dataList = [array retain];
  self.atLevel = @"level1";
  [array release];
 }

  UIActivityIndicatorView * activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
  //set the initial property
  [activityIndicator stopAnimating];
  [activityIndicator hidesWhenStopped];
  //Create an instance of Bar button item with custome view which is of activity indicator
  UIBarButtonItem * barButton = [[UIBarButtonItem alloc] initWithCustomView:activityIndicator];
  //Set the bar button the navigation bar
  [self navigationItem].rightBarButtonItem = barButton;
  //Memory clean up
  [activityIndicator release];
  [barButton release];


 [super viewDidLoad];
}



 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
 {
  NSString *level = self.atLevel;
  if([level isEqualToString:@"level2"])
  {
   return 70.0f;
  }
  else
  {
   return 40.0f;

  }
 }


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
 static NSString *FirstLevelCell = @"FirstLevelCell";

 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:FirstLevelCell];
 if(cell == nil)
 {
  cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:FirstLevelCell] autorelease];
 }

 NSInteger row = [indexPath row]; 

 NSString *level = self.atLevel;
 if([level isEqualToString:@"level2"])
 { 
  NSMutableArray *stream = [self.dataList objectAtIndex:row];
  NSString *newsTitle = [stream valueForKey:@"title"];

  if( ![newsTitle isKindOfClass:[NSString class]] )
  {
   cell.textLabel.text =  @"";
  }
  else 
  {
   cell.textLabel.text = [stream valueForKey:@"title"]; 
  }

   cell.textLabel.numberOfLines = 2;
   cell.textLabel.font =[UIFont systemFontOfSize:10];

   cell.detailTextLabel.numberOfLines = 1;
   cell.detailTextLabel.font= [UIFont systemFontOfSize:8];
   cell.detailTextLabel.text = [stream valueForKey:@"created"];


   NSData *imageURL = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://www.website.co.uk/images/stories/img.jpg"]];
   UIImage *newsImage = [[UIImage alloc] initWithData:imageURL];

   cell.imageView.image = newsImage;

   [imageURL release];
   [newsImage release];
 }
 else 
 {
  cell.textLabel.text = [dataList objectAtIndex:row];
 }

 return cell;
}



- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
 NSUInteger row = [indexPath row]; 
 NSMutableString *levelType = (NSMutableString *) [dataList objectAtIndex:row];

 if(![levelType isKindOfClass:[NSString class]])
 {
  if(self.generalNewsDetailViewController == nil)
  {
   GeneralNewsDetailViewController *generalDetail = [[GeneralNewsDetailViewController alloc] initWithNibName:@"GeneralNewsDetailView" bundle:nil];
   self.generalNewsDetailViewController = generalDetail;
   [generalDetail release];
  }

  NSDictionary *stream = [self.dataList objectAtIndex:row];

  NSString *newsTitle = [stream valueForKey:@"title"];

  if( ![newsTitle isKindOfClass:[NSString class]] )
  {
   generalNewsDetailViewController.newsTitle =  @"";
  }
  else 
  {
   generalNewsDetailViewController.newsTitle =[stream valueForKey:@"title"]; 
  }

  generalNewsDetailViewController.newsId = [stream valueForKey:@"id"];
  generalNewsDetailViewController.fullText = [stream valueForKey:@"fulltext"];
  generalNewsDetailViewController.newsImage = [stream valueForKey:@"images"];
  generalNewsDetailViewController.created = [stream valueForKey:@"created"];

  HowDo_v1AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
  [delegate.generalNewsNavController pushViewController:self.generalNewsDetailViewController animated:YES];

 }
 else
 {

  GeneralNewsTableViewController
   *generalSubDetail = [[GeneralNewsTableViewController alloc] initWithNibName:@"GeneralNewsTableView" bundle:nil];

  NSMutableArray *array;
  NSString *titleSelected = (NSString *) [dataList objectAtIndex:row];

  if([titleSelected isEqualToString:@"Publishing"])
  {
   generalSubDetail.title = @"Publishing news detail";
   array = [[NSArray alloc] initWithObjects:@"pub News1", @"pub News2",@"pub News3",nil];
   generalSubDetail.atLevel = @"level1";
  }
  else if ([titleSelected isEqualToString:@"Broadcasting"])
  {
   generalSubDetail.title = @"Broadcasting news detail";

  /// START  
 [self performSelectorOnMainThread:@selector(startIndicator) withObject:nil waitUntilDone:YES];

   if(jSONDataAccessWrapper == nil)
   {
    jSONDataAccessWrapper = [JSON_DataAccess_Wrapper alloc];
   } 
   array = [jSONDataAccessWrapper downloadJSONFeed];



 [self performSelectorOnMainThread:@selector(stopIndicator) withObject:nil waitUntilDone:YES];


   generalSubDetail.atLevel = @"level2";
  }
  else if ([titleSelected isEqualToString:@"Marketing Services"])
  {
   generalSubDetail.title = @"Marketing Services news detail";
   array = [[NSArray alloc] initWithObjects:@"Marketing News1", @"Marketing News2",@"Marketing News3",nil];
   generalSubDetail.atLevel = @"level1";
  }
  generalSubDetail.dataList = array;

  [self.navigationController pushViewController:generalSubDetail animated:YES];

  [titleSelected release];

 } 


}

- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
//- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSIndexPath *) section
{
 return [self.dataList count]; 
}

Cheers for any feedback

Frames

A: 

It is usually recommended by Apple that operations on user interface should be done on the main thread.

What you can do is to defer the callback into the main thread:

- (void)startIndicator
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [self performSelectorOnMainThread:@selector(startAnimating:) withObject:nil waitUntilDone:NO];
    [pool release];
}

- (void)startAnimating:(id)sender
{
    [(UIActivityIndicatorView *)[self navigationItem].rightBarButtonItem.customView startAnimating];
}

Check out the Thread Guide from Apple. It contains useful information.

Laurent Etiemble
Only works when I remove the :(id)sender from the startAnimating method. am i not passing a pram?
Frames84
My bad. If you pass nil to performSelectorOnMainThread, that means that the method does not take a parameter. Thus you can skip the intermediate method and make the "performSelectorOnMainThread" directly on the UIActivityIndicatorView.
Laurent Etiemble