For any smartphone user, one of the worst things that can happen is to lose cell coverage. Regardless of when it happens, it usually occurs during a call or when you need to look something up on the internet.
As mobile app developers, we have faced this problem for many years. Even the simplest of apps typically need an internet connection even if it is to only display an iAd. More sophisticated apps may need an internet connection to store data back in the cloud, whether it is a high score for a game or enterprise data logged by the CEO. Let’s take a step back and look at the current state of mobile connectivity in iOS apps.
Mobile connectivity is something that Apple addressed early on with it’s Reachability library. It uses the System Configuration framework to monitor the network state of your iOS application. To get set up, you will first need to download the sample code and add the SystemConfiguration.framework to your iOS app as shown in Figure 1.

Figure 1 : SystemConfiguration.framework should be added to your project under “Linked Frameworks and Library”.
Once added, only include the Reachability.h and Reachability.m files in your project that you downloaded earlier and don’t forget to import the Reachability.h file in your ViewController.
A very simple sample to test for internet connectivity when your application launches is found in the viewDidLoad method of your current view. You could use the following code to determine if the user has an internet connection or not:
- (void)viewDidLoad
{
[super viewDidLoad];
Reachability *networkReachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [networkReachability currentReachabilityStatus];
if (networkStatus == NotReachable) {
NSLog(@"Cannot find internet...boo!");
} else {
NSLog(@"Found internet....yea!");
}
}
When you check your debug window, you should see a message similar to the following if you have an internet connection:
2014-07-15 10:37:11.672 MobileConnectivity[7509:60b] Reachability Flag Status: -R -----l- networkStatusForFlags
2014-07-15 10:37:11.672 MobileConnectivity[7509:60b] Found internet....yea!
If you switch back to the Reachability sample project and take a look at the APLViewController.m file file you will see more sophistated samples such as: changing the host name of the server you wish to monitor; determining if a network connection changes; and how to dectect which type of network they are connected to, whether it be WiFi, WWAN, etc. I’m not going to go into those in detail as the code is already provided, but we will find out shortly that the community has greatly enhanced the Reachability project to make it simplier to use… but first let’s talk about some best practices.
From trial and error, I’ve created a list of best practices that I use personally in my own apps for addressing connectivity.
Throughout your app’s lifecycle, the internet connection can change. Your user can be driving through a poor coverage area and lose their cell signal or enter a building that has very little cell coverage. Your app needs to be able to monitor these changes and react accordingly.
If you look at the Reachability sample project again and take a look at the APLViewController.m file file, you will see a comment with the following line:
/*
Observe the kNetworkReachabilityChangedNotification. When that notification is posted, the method reachabilityChanged will be called.
*/
The code sets up a notification that reacts with the various states of internet connectivity that your app may experience as shown in Figure 2. This is extremely helpful in our second point listed below.
The goal is to make the end-users’ experience the best possible if they lose connectivity. If you are using iAd, then simply toggle the visibility of the ad to invisible. If you are writing a line-of-business app that collects data, then make sure the data is persisted locally on the device after each change. If you are displaying data from the web such as an image or site, fill the content with a non-intrusive message such as “Cannot Connect to the Internet” as shown in Figure 3 or “Check internet availability”.
The key takeaway here is to always have the end-users’ experience in mind. They don’t want to enter data twice or to think that there is a problem with your app when it is actually because they don’t have an internet connection.
You have the ability to determine if your end-user is on a cellular signal or Wifi. If you create an app that needs to download large amounts of data, then wait until they are on an Wifi connection. Not only will it save your end-users’ data plan, but it will also preserve battery life. You should also do tthe same when uploading large amounts of data, waiting until a Wifi signal is detected.
While Apple’s own Reachability library is easy to work with, it does not support GCD (Grand Central Dispatch), which allows for concurrent code execution on multicore hardware for iOS and OS X. Forunately for us, there are open-source projects that will allow us to work with GCD as well as write-cleaner code. One such library is Tony Million’s Reachability.
SystemConfiguration.framework to the linked frameworks and libraries as you did before.Reachability.h and Reachability.m files to your project.Reachability.h file into your ViewController.We can then use the following code to not only check if we have internet access, but also listen through our app’s lifecycle for connectivity.
- (void)testInternetConnection
{
__weak typeof(self) weakSelf = self;
internetReachable = [Reachability reachabilityWithHostname:@"www.google.com"];
// Internet is reachable
internetReachable.reachableBlock = ^(Reachability*reach)
{
// Update the UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
//Make sure user interaction on whatever control is enabled
});
};
// Internet is not reachable
internetReachable.unreachableBlock = ^(Reachability*reach)
{
// Update the UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No network connection"
message:@"You must be connected to the internet to use this app."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
//Make sure user interaction on whatever control is disabled
});
};
[internetReachable startNotifier];
}
Looking at this code, we can see that we are checking to see if google.com is available and if it is we use GCD to give the developer the option to enable user interaction on a control. If it cannot find a valid internet connection, then is displays a UIAlertView and gives the developer the option to disable any controls the user may interact with. The last line starts the notifier that will call this method again if the user loses internet connectivity during the lifetime of the app.
A sample of this is shown in Figure 4, where I enabled and disable a TableView (containing my RSS feed)when I lost internet connectivity.
Update 10/24/16: The Data Sync framework is no longer a supported option.
Telerik’s Data Sync Framework tackles this problem two-fold.
TelerikUI.framework, SystemConfiguration.framework and libsqlite3.0.dylib to the linked frameworks and libraries in your project properties.ViewController. TKEverliveClient* everliveClient = [TKEverliveClient clientWithApiKey:self.apiKey
accessToken:self.accessToken serviceVersion:@1];
TKDataSyncReachabilityOptions options = TKSyncIn3GNetwork | TKSyncInWIFINetwork;
TKDataSyncPolicy* thePolicy = [[TKDataSyncPolicy alloc] initForSyncOnDemandWithReachabilityOptions:options
conflictResolutionType:TKPreferLocalInstance
syncTimeout:100.0];
_theContext = [[TKDataSyncContext alloc] initWithLocalStoreName:@"localGameDb" cloudService:everliveClient syncPolicy:thePolicy];
[_theContext setDelegate:self];
[_theContext registerClass:[VideoGame class] withPrimaryKeyField:@"gameId" asAutoincremental:NO];
This code creates a TKEverliveClient instance passing in the apiKey and accessToken for the current user. Then sets up the TKDataSyncPolicy options and initializes the TKDataSyncContext with our everliveClient credentials as well as the synchronization policy we defined earlier. It also registers the class that holds the fields that we wish to persist.
In Figure 5, we are going to persist two fields, one called gameID and the other gameTitle. We have two buttons to add an item locally and another button that will sync all the items that are not stored in the backend service (but are still persisted locally). After adding an item, we will display it in our backend service, then disconnect from the internet and add several more items then reconnect to the internet and sync manually.
Today we looked at several ways that iOS developers can check for mobile connectivity in their iOS apps. Who would have thought that mobile connectivity could be so complicated, yet so easy to handle with the proper libraries. From Apple’s own Reachability and community contributions to it, to Telerik’s fully featured data sync framework – you have plenty of options at your disposal. Whatever library you choose, you will want to make sure that you implement the best practices so that your users come back to not only your current app, but apps you create in the future!
Michael Crump