From AAPL’s developer website:
If your application provides functionality that requires access to a network, it’s very important that your code include a customer alert or notification when the network is not available.
The Reachability sample application demonstrates how to use the System Configuration Reachability API to monitor the network state of an iPhone or iPod touch. Use this sample code to learn how to detect the absence of Wi-Fi and Wireless Wide Area Network (WWAN) services so your application knows when it’s necessary to produce a network error alert.
Your users will appreciate knowing when an application has no network access — and missing “network alerts” is the third most common reason for applications being returned to developers for modification.
I had to address this issue when implementing the in-app store for Demine. It’s not too much work once you see how it’s supposed to be done, and AAPL’s Reachability
class can be used right out of the box. Read on for some implementation notes.
The Goal
For Demine, I didn’t want to implement a generic network alert. 99% of the time, it doesn’t matter whether the network is available or not, and needless alert boxes (“Oh, hey, if you wanted to do X, which you probably don’t, it wouldn’t work.”) just annoy the user. I wanted to implement a network alert that would be specific to the Store screens, and which would pop up when a network fault would interfere with their proper operation.
Reachability
The Reachability
class wraps the SCNetworkReachability*
stuff. It can be copied directly from the Reachability sample application into your project. The only wrinkle is that you must add the SystemConfiguration.framework
to your project.
Preliminaries
To persist the Reachability
object I’ll be creating, I add this to the Store
declaration:
Reachability* reachability;
I also add a property to the Store
extension definition in the implementation file:
@property (nonatomic, retain) Reachability* reachability;
… and a @synthesize reachability;
to the Store
implementation itself.
Code
There are two basic things to add. First, in viewDidLoad
, I observe the kReachabilityChangedNotification
notification, and set up the Reachability
object:
- (void)viewDidLoad
{
// … snip …
// Check network
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reachabilityChanged:)
name:kReachabilityChangedNotification
object:nil];
self.reachability = [Reachability reachabilityWithHostName:@"www.apple.com"];
[self.reachability startNotifier];
// … snip …
}
Second, I define the reachabilityChanged:
extension method:
- (void)reachabilityChanged:(NSNotification*)note
{
Reachability* r = [note object];
NetworkStatus ns = r.currentReachabilityStatus;
if (ns == NotReachable)
{
NSString* msg = @"Network problems have rendered the iTunes store inaccessible; please try again later.";
UIAlertView* av = [[UIAlertView alloc] initWithTitle:nil
message:msg
delegate:self
cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
[av show];
[av release];
}
}
There’s also a little bit of cleanup in dealloc
:
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
// … snip …
[reachability release];
// … snip …
}
Remarkably, the NSNotificationCenter
business in dealloc
doesn’t appear to be necessary, although it seems like it should be required to avoid crashes. (In fact, I accidentally omitted it from the Demine app currently on offer in the app store.) Store
inherits from UITableViewController
, so maybe the latter class’ dealloc
includes a similar statement.
The final touch is a simple alert view handler, which dismisses the store on a network failure:
- (void)alertView:(UIAlertView*)av clickedButtonAtIndex:(NSInteger)buttonIndex
{
[self dismiss];
}
(Note that dismiss
is defined elsewhere.)