Posts Tagged ‘snippet’

Sometimes it’s crucial in your app, that you know whether your users are connected to a wireless network (EDGE, 3G, WiFi) or not.
I’ve been using the following snippet quite a lot in the past and thought, maybe someone might find it useful too.

In order to get this to work, you need to follow these steps:

1) Import the “SystemConfiguration.framework” framework into your app.

2) Add the following lines into the .m file of the class, you want to make the calls from (right below your #import lines):

#include <netinet/in.h>
#import <SystemConfiguration/SCNetworkReachability.h>

3) Finally add a new method to your class:

- (BOOL)connectedToNetwork  {
// Create zero addy
	struct sockaddr_in zeroAddress;
	bzero(&zeroAddress, sizeof(zeroAddress));
	zeroAddress.sin_len = sizeof(zeroAddress);
	zeroAddress.sin_family = AF_INET;
	// Recover reachability flags
	SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr*)&zeroAddress);
	SCNetworkReachabilityFlags flags;
	BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
	CFRelease(defaultRouteReachability);
	if (!didRetrieveFlags)
	{
		NSLog(@"Error. Could not recover network reachability flags");
		return 0;
	}
	BOOL isReachable = flags & kSCNetworkFlagsReachable;
	BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
	return (isReachable && !needsConnection) ? YES : NO;
}

3a) Same method, but with updated code as suggested by Ariel in comments below

<pre>- (BOOL)connectedToNetwork  {
// Create zero addy
	struct sockaddr_in zeroAddress;
	bzero(&zeroAddress, sizeof(zeroAddress));
	zeroAddress.sin_len = sizeof(zeroAddress);
	zeroAddress.sin_family = AF_INET;
	// Recover reachability flags
	SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr*)&zeroAddress);
	SCNetworkReachabilityFlags flags;
	BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
	CFRelease(defaultRouteReachability);
	if (!didRetrieveFlags)
	{
		NSLog(@"Error. Could not recover network reachability flags");
		return 0;
	}
	BOOL isReachable = flags & kSCNetworkFlagsReachable;
	BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
//below suggested by Ariel
	BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;
        NSURL *testURL = [NSURL URLWithString:@"http://www.apple.com/"]; //comment by friendlydeveloper: maybe use www.google.com
        NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
        //NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:nil]; //suggested by Ariel
        NSURLConnection *testConnection = [[[NSURLConnection alloc] initWithRequest:testRequest delegate:nil] autorelease]; //modified by friendlydeveloper
        return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO;</pre>
}

Now, you can easily check, if there is a network connection or not, like:

if ([self connectedToNetwork]) {
//yes we're connected
}
else {
//no we're not connected
}

Hope, you enjoy it.
Feedback always welcome…

Usually, iPhone apps are built using some kinda hierarchy:

  • ->AppDelegate
  • ->-> RootViewController
  • ->->->OtherViewController(s)
  • ->->->->Views

On various occasions, you might want to get some information from your AppDelegate (e.g. values, array infos, etc…).

You might already know, that there is a simple line of code, which gives you access to your AppDelegate:


AppDelegate *mainDelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];

If you need access to your AppDelegate only once or twice in a View or ViewController, this is the best way to go. However, if you have several methods in your View or ViewController and some of them need AppDelegate access, you always have to repeat the above line of code first.

In order to avoid that, there is a simple way, to permanently implement AppDelegate access in your View or ViewController:


//this example assumes, that we are using a ViewController

//inside .h file

//below #import lines

@class AppDelgate;

@interface MyViewController : UIViewController {

AppDelegate *mainDelegate;

}

//@property (nonatomic, retain) AppDelegate *mainDelegate; //error correction here - no need to @property

@end

//inside .m file

//below #import lines

#import "AppDelegate.h"

@implementation MyViewController

@synthesize mainDelegate;

- (void)viewDidLoad {

mainDelegate = (AppDelegate*)[[UIApplication sharedApplication]delegate];

}

- (void)dealloc {

//[mainDelegate release]; //error correction here - the mainDelegate object does not need to be released, since we do not call alloc init on it.

[super dealloc];

}

//now you have access to your AppDelegate in every method

//example: we assume, that our AppDelegate holds three different integer values we want to grab

- (void)methodA {

int numberA = mainDelegate.numberA;

}

- (void)methodB {

int numberB = mainDelegate.numberB;

}

- (void)methodC {

int numberC = mainDelegate.numberC;

}

As you can see, it’s slightly more work to implement AppDelegate access than just using that single line of code over and over again. However, in my opinion it’s well worth the time, especially if your .m file holds many methods.

Your code appears much cleaner that way.

An App, you might like:
We recommend…
You might also like…
Get Adobe Flash playerPlugin by wpburn.com wordpress themes