Online Book Reader

Home Category

iOS Recipes - Matt Drance [62]

By Root 260 0
as is and easily extended to either go further or address your own requirements more directly.

Recipe 31 Tame the Network Activity Indicator

Problem

Your application performs downloads and uploads in multiple places, queuing or parallelizing them under heavy user activity. You need to reliably display network status without actively tracking every network operation.

Solution

We can use the networkActivityIndicatorVisible property on UIApplication to conveniently show and hide the network “spinner” in the status bar. This binary switch has no context, however. If we write an application that performs concurrent uploads and downloads, it quickly becomes hard to accurately report ongoing activity. Showing the indicator when every transaction starts is easy, but how do we know when to hide it? Whether we’re using NSURLConnection or NSStream, our networking code should not necessarily be responsible for maintaining the context required to manage the network activity indicator. We’ll solve this problem with a category on UIApplication that tracks network connections, automatically showing the indicator when activity begins and hiding it when it is finished. By using a category, we can call the existing UIApplication instance rather than managing another object. This especially makes sense since the activity indicator itself is managed by UIApplication.

This PRPNetworkActivity category maintains a read-only count of active connections. Two methods, ‑prp_pushNetworkActivity and ‑prp_popNetworkActivity, allow any code to notify the application of network activity. A ‑prp_resetNetworkActivity method clears the current state and starts from scratch.

NetworkActivityCenter/Classes/UIApplication+PRPNetworkActivity.h

@interface UIApplication (PRPNetworkActivity)

@property (nonatomic, assign, readonly) NSInteger prp_networkActivityCount;

- (void)prp_pushNetworkActivity;

- (void)prp_popNetworkActivity;

- (void)prp_resetNetworkActivity;

@end

Remember that because this is a category, it’s important to prefix all of the method names to ensure they don’t conflict with any methods Apple adds to UIApplication in future SDK releases.

The implementation is very simple: we declare a static prp_networkActivityCount variable, which the ‑prp_pushNetworkActivity and ‑prp_popNetworkActivity methods respectively increment and decrement. A simple getter method exposes the count in a read-only fashion.

NetworkActivityCenter/Classes/UIApplication+PRPNetworkActivity.m

- (NSInteger)prp_networkActivityCount {

@synchronized(self) {

return prp_networkActivityCount;

}

}

- (void)prp_pushNetworkActivity {

@synchronized(self) {

prp_networkActivityCount++;

}

[self prp_refreshNetworkActivityIndicator];

}

- (void)prp_popNetworkActivity {

@synchronized(self) {

if (prp_networkActivityCount > 0) {

prp_networkActivityCount--;

} else {

prp_networkActivityCount = 0;

NSLog(@"%s Unbalanced network activity: count already 0.",

__PRETTY_FUNCTION__);

}

}

[self prp_refreshNetworkActivityIndicator];

}

A few notes about this approach:

We use a global to store the activity count, but our category methods operate on an instance of UIApplication. Always be careful when sharing statics between object instances. An ideal solution might use the associated object approach explained in Recipe 40, Store Data in a Category , but since there is only a single UIApplication instance in a given app, we stuck with the global in the interest of simplicity.

The methods listed earlier access the activity count while synchronizing on self, which is the shared application instance since we’ve written a category on UIApplication. We have added this synchronization because networking code that uses these category methods is likely to run on multiple threads. There is more than one way to synchronize Objective-C code, so we’ve chosen what we saw as the clearest solution.

The ‑prp_refreshNetworkActivityIndicator method sets the standard networkActivityIndicatorVisible property on UIApplication according to the current activity count:

Return Main Page Previous Page Next Page

®Online Book Reader