@DavidBemerguy's approach is a good start, but you'd typically want to implement it with dispatch_group_notify
to hide your indicator. That said, IMO, you don't need GCD here. You just need a NetworkIndicatorController
.
Create an object (the controller) that listens to notifications like DidStartNetworkActivity
and DidStopNetworkActivity
. Post notifications when you start or stop. Inside the controller, keep a count and when it hits 0, hide the indicator. Something like this (totally untested, just typing here, and I've been writing exclusively in Swift for the last few days, so forgive any missing semicolons):
.h:
extern NSString * const DidStartNetworkActivityNotification;
extern NSString * const DidStopNetworkActivityNotification;
@interface NetworkIndicatorController
- (void) start;
- (void) stop;
@end
.m
@interface NetworkIndicatorController ()
@property (nonatomic, readwrite, assign) NSInteger count;
@end
@implementation NetworkIndicatorController
- (void)start {
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self name:DidStartNetworkActivityNotification selector:@selector(didStart:) object:nil];
[nc addObserver:self name:DidStopNetworkActivityNotification selector:@selector(didStop:) object:nil];
self.count = 0;
}
- (void)stop {
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self name:DidStartNetworkActivityNotification object:nil];
[nc removeObserver:self name:DidStopNetworkActivityNotification object:nil];
}
- (void)didStart:(NSNotification *)note {
dispatch_async(dispatch_get_main_queue(), {
self.count = self.count + 1;
[[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:YES];
});
}
- (void)didStop:(NSNotification *)note {
dispatch_async(dispatch_get_main_queue(), {
self.count = self.count - 1;
if (self.count <= 0) {
[[UIApplication sharedApplication]setNetworkActivityIndicatorVisible:NO];
}
});
}
You could get similar stuff with dispatch_group, but I think this is simpler. The problem with the dispatch group approach is keeping track of when you do and don't want to call dispatch_notify. I'm sure the final code isn't that hard, but it's trickier to think about all the possible race conditions.
You could also just directly call -startNetworkActivity
and -stopNetworkActivity
directly on an instance of this object that you pass around rather than using notifications.