39

I've found several examples of code to do what I want (check for reachability), but none of it seems to be exact enough to be of use to me. I can't figure out why this doesn't want to play nice.

I have the reachability.h/m in my project, I'm doing

#import <SystemConfiguration/SystemConfiguration.h>

And I have the framework added. I also have:

#import "Reachability.h"

at the top of the .m in which I'm trying to use the reachability.

Reachability* reachability = [Reachability sharedReachability];
[reachability setHostName:@"http://www.google.com"];    // set your host name here
NetworkStatus remoteHostStatus = [reachability remoteHostStatus];

if(remoteHostStatus == NotReachable) {NSLog(@"no");}
else if (remoteHostStatus == ReachableViaWiFiNetwork) {NSLog(@"wifi"); }
else if (remoteHostStatus == ReachableViaCarrierDataNetwork) {NSLog(@"cell"); }

This is giving me all sorts of problems. What am I doing wrong? I'm an alright coder, I just have a hard time when it comes time to figure out what needs to be put where to enable what I want to do, regardless if I want to know what I want to do or not. (So frustrating)

Update: This is what's going on. This is in my viewcontroller, which I have the

#import <SystemConfiguration/SystemConfiguration.h>

and

#import "Reachability.h"

set up with. This is my least favorite part of programming by far.reachability problems
(source: sneakyness.com)


FWIW, we never ended up implementing this in our code. The two features that required internet access (entering the sweepstakes, and buying the dvd), were not main features. Nothing else required internet access.

Instead of adding more code, we just set the background of both internet views to a notice telling the users they must be connected to the internet to use this feature. It was in theme with the rest of the application's interface, and was done well/tastefully. They said nothing about it during the approval process, however we did get a personal phone call to verify that we were giving away items that actually pertained to the movie. According to their usually vague agreement, you aren't allowed to have sweepstakes otherwise.

I would also think this adheres more strictly to their "only use things if you absolutely need them" ideaology as well.

Here's the iTunes link to the application, EvoScanner.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Sneakyness
  • 5,305
  • 4
  • 33
  • 39
  • 1
    in what way is it not doing what you want? we can't tell from this code here what you want or how it isn't working. does it not compile, does it not produce the right results in some situations, or what? – David Maymudes Dec 07 '09 at 17:56
  • I updated the question to reflect my problems. Sorry for not being more specific. – Sneakyness Dec 07 '09 at 19:15
  • 2
    Turns out we never needed it anyways! They do say **that the best code is the code you never have to write!** :D – Sneakyness Dec 18 '09 at 01:53

5 Answers5

65

From your screen shot, it seems like you do not have Reachability added to your project. You must download Reachability from Apple:

https://developer.apple.com/library/content/samplecode/Reachability/Introduction/Intro.html

And add both .h and .m files to your project.

Update: You noted you have Reachability. But looking at the most recent version, I can see why you have the errors you listed - they changed the API and you are probably using sample code you found somewhere else. Try:

in .h file:

//import Reachability class
#import "Reachability.h"

// declare Reachability, you no longer have a singleton but manage instances
Reachability* reachability;

in .m file:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNetworkChange:) name:kReachabilityChangedNotification object:nil];

reachability = [Reachability reachabilityForInternetConnection];
[reachability startNotifier];

NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];

 if(remoteHostStatus == NotReachable) {NSLog(@"no");}
else if (remoteHostStatus == ReachableViaWiFi) {NSLog(@"wifi"); }
else if (remoteHostStatus == ReachableViaWWAN) {NSLog(@"cell"); }

.....

- (void) handleNetworkChange:(NSNotification *)notice
{

  NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];

   if(remoteHostStatus == NotReachable) {NSLog(@"no");}
else if (remoteHostStatus == ReachableViaWiFi) {NSLog(@"wifi"); }
else if (remoteHostStatus == ReachableViaWWAN) {NSLog(@"cell"); }
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
Kendall Helmstetter Gelner
  • 74,769
  • 26
  • 128
  • 150
  • No I have those both added, though that is a good thing to mention to check. How do I include them so that I can use them where I need them to be used? This is really getting me down. – Sneakyness Dec 07 '09 at 22:16
  • 1
    you need to have an import statement at the top of your file. import Reachability.h – bpapa Dec 08 '09 at 03:16
  • I will do this! I never saw the update to this on SO. I am sorry for not checking back faster. We actually finished the app without this, so I will likely go back and mess around with it this weekend. Thanks! – Sneakyness Dec 12 '09 at 04:14
  • @KendallHelmstetterGelner nikoz' answer (below) seems to work. Is the `NSNotification` async piece really necessary? Thanks! – Dan Rosenstark Jun 27 '14 at 23:10
  • 1
    It is better to support the callback if you need to check the status later rather than creating a new Reachability object every time, especially if you are looking for reachability to a specific host instead of just general internet connectivity. – Kendall Helmstetter Gelner Jul 02 '14 at 02:06
  • For my own notes, since I keep coming back here: Just checked the readme.txt here (https://developer.apple.com/library/IOs/samplecode/Reachability/Listings/ReadMe_txt.html). Turns out that it's blocking in the synchronous form, so while you shouldn't do it, it's fine to do without including the async block ;) – Dan Rosenstark Aug 01 '14 at 03:50
29
[reachability setHostName:@"http://www.google.com"];

Attention! I encountered the problem that it's always "NotReachable" if the http:// prefix is used.

Raphael

Raphael Schaad
  • 1,659
  • 1
  • 17
  • 17
7

Here's the right code as it works for me today!!!

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(handleNetworkChange:) name: kReachabilityChangedNotification object: nil];

reachability = [Reachability reachabilityForInternetConnection];

[reachability startNotifier];

NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];

if(remoteHostStatus == NotReachable) {NSLog(@"no");}
else if (remoteHostStatus == ReachableViaWiFi) {NSLog(@"wifi"); }
else if (remoteHostStatus == ReachableViaWWAN) {NSLog(@"cell"); }
nikoz
  • 281
  • 4
  • 4
3

Do you have the following code anywhere?

[reachability startNotifier];

if your reachability code is from apple's example, then you need to do that before it can start reporting status updates to you.

Kevlar
  • 8,804
  • 9
  • 55
  • 81
  • do you need to do that even if you're just querying the immediate status like the code above rather than waiting for a notification? – David Maymudes Dec 07 '09 at 18:17
  • i believe so; i could be wrong, but apple's reachability code basically runs in a separate thread that checks reachability on a set interval i believe, and you need to start that process before it can report the status back to you. – Kevlar Dec 07 '09 at 18:20
  • 1
    You CANNOT query immediate status. Reachability works by you attempting to make a connection, and then Reachability starts issuing notifications as to state. The closest you can do is to try some small URL result you know you exists and then wait for notifications. Apple was very explicit at WWDC that this is the way to do reachability. – Kendall Helmstetter Gelner Dec 07 '09 at 18:27
  • Also, I have not used [reachability startNotifier] in my code but I do see Reachability updates (from Apple's code). – Kendall Helmstetter Gelner Dec 07 '09 at 18:28
  • 1
    Seconding Kendall, you should follow Apple's Reachability sample (make sure you are using the latest version, which is 2.0 I believe) to a T. This includes checking for reachability asynchronously. If you do it synchronously and don't get rejected by Apple, your app WILL crash at times once it's in the wild. – bpapa Dec 07 '09 at 18:52
  • This did nothing for me. Not crashing and not getting rejected are priorities of mine. Thanks for the info, guys. – Sneakyness Dec 07 '09 at 19:15
  • 1
    The ReadMe.txt of the Reachability demo only warns against synchronous checking of hostName reachability: "You can use the API synchronously, but do not issue a synchronous check by hostName on the main thread. If the device cannot reach a DNS server or is on a slow network, a synchronous call to the SCNetworkReachabilityGetFlags function can block for up to 30 seconds trying to resolve the hostName. If this happens on the main thread, the application watchdog will kill the application after 20 seconds of inactivity." – ohhorob Dec 08 '09 at 07:47
-2

change this

reachability = [Reachability reachabilityForInternetConnection];

to this

reachability = [[Reachability reachabilityForInternetConnection] retain];
mhrrt
  • 977
  • 9
  • 18