views:

126

answers:

4

I'm using two threads in an iPhone app for the first time and I've run into a problem. In this prototype, I have a view controller that loads a local web page. I want an activity indicator to show until the page has finished loading. With the code below, the activity indicator starts, the page loads properly, but the activity indicator does not stop or hide. It doesn't look like the "loading" function ever gets called.

What am I doing wrong?

- (void)viewDidLoad {
 [self.view addSubview:activityIndicator];
 [activityIndicator startAnimating];
 [NSThread detachNewThreadSelector:@selector(getData) toTarget:self withObject:nil];
 [super viewDidLoad];
}
- (void)getData {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 [detailWebView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"page1" ofType:@"html"]isDirectory:NO]]];
 [NSTimer scheduledTimerWithTimeInterval: (1.0/2.0) target:self selector:@selector(loading) userInfo:nil repeats:YES];
 [pool release];
}
- (void)loading {
 if(!detailWebView.loading){
 [activityIndicator stopAnimating];
 [activityIndicator removeFromSuperview];
 }
+1  A: 

You 'd betetr stop the activity indicator in the webview delegate method :

-(void)webViewDidFinishLoad:(UIWebView*)webView
Benj
Yes... actually I think there is no need for threading here at all.
DarkDust
This was my simple prototype. In the full version I'm going to be parsing a large XML file, so I thought I'd better figure out how to run multiple threads.
Phil John
A: 

Have you added debug output to loading to whether it gets called ? The code sure looks like that, it should get called after 0.5 seconds and I'd guess that detailWebView is still loading then.

Also, GUI stuff should be run on the main thread, so you may need to do:

- (void)loading {
  if(!detailWebView.loading){
    [activityIndicator performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:YES];
    [activityIndicator performSelectorOnMainThread:@selector(removeFromSuperView) withObject:nil waitUntilDone:YES];
  }
}
DarkDust
I think this is probably the solution to the problem. I guess I wasn't making sure that the actions were on the main thread. I tried this code but the app crashed. If I just used the "stopAnimating" line it did stop it. I guess there's a problem with the removeFromSuperView command that I need to look at.
Phil John
OK Perhaps I was a bit premature in my last comment. It was working because I'd commented out some code (doh!). I added some debug code and I can now see that the loading function never gets called. Is it still valid to use a target of self in NSTimer in this multiple thread situation?
Phil John
I suggest you avoid threads altogether for this and do it like kubi suggested, that's really the correct solution and won't create headaches.
DarkDust
Thanks. I'll try it that way.
Phil John
+1  A: 

There's an easier way to do this without creating your own thread.

- (void)viewDidLoad {
    [self.view addSubview:activityIndicator];
    [activityIndicator startAnimating];
    [detailWebView setDelegate:self];
    [detailWebView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"page1" ofType:@"html"]isDirectory:NO]]];
    [super viewDidLoad];
}

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [activityIndicator stopAnimating];
}
kubi
A: 

You're using a webview, which already provides a mechanism to know when a load has finished, and already loads data asynchronously - the use of a custom thread really isn't needed.

Register your object as the UIWebView's delegate. Call loadRequest on the UIWebView and start animating the progress indicator. Stop animating the progress indicator in:

-(void)webViewDidFinishLoad:(UIWebView*)webView

This method is defined by the UIWebViewDelegate protocol - make sure your object implements this protocol. You implement this method:

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [activityIndicator stopAnimating];
}

http://developer.apple.com/iphone/library/documentation/uikit/reference/UIWebViewDelegate_Protocol/Reference/Reference.html

dannywartnaby