views:

390

answers:

2

Hello,

I am having a bit of a problem here, I am let the user upload some video to the server however I am having some difficulties managing a view that I am using to illustrate its progress, I know why the problem is happening and i found a way around it (sort of) here my problem

So if one tries to make some code that looks something like this (in a UIViewController

-(void)uploadMovie
{
   UIActivityView indicator=new...
  [self.view addSubview:indicator]
   [uploader UploadMyMovie:data]

 }

This code wont work, the uploader will lock the controller and will not allow time for the indicator to come on screen in time, i found waiting for a few seconds before calling the uploader works but i took another approach.

The approach was to start a new thread for the uploader and have a protocol in which the uploader object informs the UIViewController (or some delegate) when it starts uploading, its progress, and when it finishes uploading. Something like

     -(void)uploadMovie
    {
       UIActivityView indicator=new...
      [self.view addSubview:indicator]
       NSThread *thread=...
       [thread start]
     }

the delegate methods look something like this

    #pragma mark UploadProgressDelegate

-(void)didStartUploading
{

    progressLabel= [[UILabel alloc] initWithFrame:CGRectMake(93, 240, 116, 32)];
    ind= [[UIActivityIndicatorView alloc]   initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    ind.center=self.view.center;
    [progressLabel setTextColor:[UIColor blackColor]];
    [progressLabel setText:@"TEST"];
    [self.view addSubview:progressLabel];
    [self.view addSubview:ind];
    [ind startAnimating];
    [self.view bringSubviewToFront:progressLabel];
    [ind setHidesWhenStopped:TRUE]; 
    [self.view setUserInteractionEnabled:FALSE];
}
-(void)progressUpdate:(NSString*)progress
{
     [progressLabel setText:progress];
}
-(void)didEndUploading;
{
    [progressLabel removeFromSuperview];
    [ind stopAnimating];
    [ind removeFromSuperview];
    [progressLabel release];
    [ind release];
    [self.view setUserInteractionEnabled:TRUE];
}

This works great and the indicator shows and everything, then i decided to let the user see the progress by adding a UILabel (reflected in the code above), howeverr for this the solution does not work, the label does not display and ofcourse no updates...

I was wondering if anyone has encounter this situation and has come up with a solution for it? or if you can possibly see from the code above why the label isnt showing...

Thanks

+1  A: 

in some cases, I've found that I need to go back to the main thread to do certain things...

so in your delegate methods you'd do

[self performSelectorOnMainThread: @selector(updateLabel:) withObject:newLabelText waitUntilDone:NO];

and then

- (void) updateLabel:(NSString *)newLabelText
{
    [progressLabel setText:newLabelText];
}

I'm not sure what the rules are for what things have to be done on the main thread rather than in the background, though.

David Maymudes
Why did someone mark this guy down, he didnt know from the context where j had to make that call, but i did have to make that call, thanks for the help
Daniel
thanks for your support :-)
David Maymudes
+1  A: 

UIKit is not thread-safe. If you're updating a UI element, you need to sync back into the main thread or all bets are off.

Nick Veys
What do u mean by sync to the main thread
Daniel
Be in the main thread. If you mess w/UI objects outside of the main thread your results will be inconsistent. It's simply not thread-safe.
Nick Veys
Ah, right...that did it, thanks!
Daniel