Better way of handling network activity indicator

Since iOS 2.0 application could control network activity indicator in the status bar. Responsible application should show it when network access is in progress and hide when all network activities are done.
Network Activity Indicator
This could be achieved by using networkActivityIndicatorVisible property of UIApplication.

[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
// do some network stuff
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

This approach works great if you have only one place where network access is possible. And there is only one thread.

But we’re living in a very complex world and, usually, we could have several threads accessing networks. So we can’t just show and hide indicator. We have to show it when first thread starts network activities and hide when last thread stops activities.

So, let’s count all network activities!

@interface NANetworkActivityIndicator : NSObject

+(instancetype)defaultIndicator;

-(void)startActivity;
-(void)stopActivity;

@end

We’ll have singleton object to control network activity indicator. Whenever your code starts network activity you should call -startActivity and when this network activity finishes you should call -stopActivity. Simple!

Now, let’s implement this simple class.

@interface NANetworkActivityIndicator()
{
    NSUInteger _numberOfActivities;
}

@end

@implementation NANetworkActivityIndicator

+ (instancetype)defaultIndicator
{
    static dispatch_once_t onceToken;
    static NANetworkActivityIndicator *_defaultIndicator;
    dispatch_once(&onceToken, ^{
        _defaultIndicator = [[NANetworkActivityIndicator alloc] init];
    });
    return _defaultIndicator;
}

-(void)startActivity
{
    @synchronized(self)
    {
        _numberOfActivities++;
        [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    }
}

-(void)stopActivity
{
    @synchronized(self)
    {
        if (_numberOfActivities)
        {
            _numberOfActivities--;
        }
        [UIApplication sharedApplication].networkActivityIndicatorVisible = (_numberOfActivities > 0);
    }
}

@end

We’re using @synchronized directive to make method calls thread safe. Since these operations will not happen too often, this will not be a significant performance impact.

No GitHub project this time. This code is too simple (and could be copy-pasted under terms of MIT License).

However, I’d recommend reading Apple documentation on thread safety and UIApplication class reference.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s