iPhone Activity Indicator 5-Apr-2010 10:08 AM
Edit FancyEdit New New Blog Upload All Recent Home Logout

iPhone Activity Indicator bit

Here's something I've implemented that makes it easier to handle working with the status bar activity indicator. This makes things work "as expected" from multiple download/activity threads.

Note: there is likely a better way to do all of this, but this is what I threw together, and it works great for me.

In AppDelegate.h

extern NSString * Net_Indicator_ON;
extern NSString * Net_Indicator_OFF;
#define NET_INDICATOR_ON()      [[NSNotificationCenter defaultCenter] postNotificationName:Net_Indicator_ON object:nil];
#define NET_INDICATOR_OFF()     [[NSNotificationCenter defaultCenter] postNotificationName:Net_Indicator_OFF object:nil];

@interface MyAppDelegate : NSObject <UIApplicationDelegate> {
// ...
int netIndCount;
// ...
}

In AppDelegate.m

#pragma mark -
#pragma mark activity indicator fun stuff

// aid in dealing with being called from a non-main thread
- (void)netIndicatorOn_actual {
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
}
- (void)netIndicatorOff_actual {
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
}

// what is called from the notification catcher
- (void)netIndicatorOn {
    // the way this works. always turn it on, but increment the count...
    netIndCount++;
    [self performSelectorOnMainThread:@selector( netIndicatorOn_actual ) withObject:nil waitUntilDone:NO];
}

- (void)netIndicatorOff {
    // when we request that it be turned off, we decrement the counter
    // if the counter dips to 0, then we are the last requestor, actually turn it off.
    netIndCount--;
    if( netIndCount <= 0 ) {
        netIndCount = 0;
        [self performSelectorOnMainThread:@selector( netIndicatorOff_actual ) withObject:nil waitUntilDone:NO];
    }
}

#pragma mark -
#pragma mark standard implementation (3.2+ shown)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{    
    // ...

    netIndCount = 0;
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( netIndicatorOn ) name:Net_Indicator_ON object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector( netIndicatorOff ) name:Net_Indicator_OFF object:nil];

    // ...
}

Then, in your threaded download code; do something like this:

- (void)indon
{
    NET_INDICATOR_ON();
}

- (void)main 
{
    // make sure the indicator is turned on immedately, without
    // needing to deal with runloop blocking stuff.
    [self performSelectorInBackground:@selector(indon) withObject:self];

    NSURLRequest * nsur = [NSURLRequest requestWithURL:url];
    NSURLResponse * nsresp;
    NSError * error;
    NSData * theData = [NSURLConnection sendSynchronousRequest:nsur returningResponse:&nsresp error:&error];

    if( theData ) {
//      NSLog( @"%@ - Data retrieved properly!", [lobe objectForKey:@"INDEX"]);

    } else {
        NSLog( @"%@ - Data FAILED RETRIEVALING!", [lobe objectForKey:@"INDEX"]);
    }
    NET_INDICATOR_OFF();
}