15

How do I check internet connection in an OS X cocoa application? Can Apple's iOS Reachability example code be reused for this purpose?

Thanks,

Nava

dfeuer
48.8k5 gold badges69 silver badges171 bronze badges
asked Jun 8, 2010 at 8:40
1
  • This isn't a particularly great solution, which is why I'm listing it as a comment instead of as an answer, but if you set a WebView's frameLoadDelegate, it'll receive when a provisionalLoadError occurs, which is pretty much immediate if there's no web connection. Since I'm using a WebView (from the WebKit.framework) anyways, I'm just throwing up an error message as soon as it gets the provisionalLoadError. Commented May 12, 2013 at 4:02

5 Answers 5

18

The current version of Reachability code (2.2) listed on Apple's site and referenced above does NOT compile as-is for a Mac OS X Cocoa application. The constant kSCNetworkReachabilityFlagsIsWWAN is only available when compiling for TARGET_OS_IPHONE and Reachability.m references that constant. You will need to #ifdef the two locations in Reachability.m that reference it like below:

#if TARGET_OS_IPHONE
 (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',
#else
 0,
#endif

and

#if TARGET_OS_IPHONE
if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
{
 // ... but WWAN connections are OK if the calling application
 // is using the CFNetwork (CFSocketStream?) APIs.
 retVal = ReachableViaWWAN;
}
#endif
Tibidabo
21.5k5 gold badges93 silver badges88 bronze badges
answered Jun 16, 2011 at 17:21
Sign up to request clarification or add additional context in comments.

1 Comment

@dbainbridge you want '-',, not 0, above.
10

This code will help you to find if internet is reachable or not:

-(BOOL)isInternetAvail
{
 BOOL bRet = FALSE;
 const char *hostName = [@"google.com" cStringUsingEncoding:NSASCIIStringEncoding];
 SCNetworkConnectionFlags flags = 0;
 if (SCNetworkCheckReachabilityByName(hostName, &flags) && flags > 0) 
 {
 if (flags == kSCNetworkFlagsReachable)
 {
 bRet = TRUE;
 }
 else
 {
 }
 }
 else 
 {
 }
 return bRet;
}

For more information you can look at the iphone-reachability

answered Jun 8, 2010 at 9:03

2 Comments

This will work for cocoa. For iphone you might have replace the flags and method name based on SDK documentation.
This function is deprecated, see my answer for the equivalent solution proposed by Apple.
7

Unicorn's solution is deprecated, but you can get equivalent results using the following code:

SCNetworkReachabilityRef target;
SCNetworkConnectionFlags flags = 0;
Boolean ok;
target = SCNetworkReachabilityCreateWithName(NULL, hostName);
ok = SCNetworkReachabilityGetFlags(target, &flags);
CFRelease(target);
udondan
60.5k21 gold badges199 silver badges182 bronze badges
answered May 11, 2012 at 16:16

2 Comments

What frameworks are required for this? I can't compile it in my app with just the Cocoa and WebKit frameworks included in my app.
Once you get the flags: On my Mac, the flags show kSCNetworkReachabilityFlagsReachable even when Airport is off and there is no direct connection -- the "reachability" flag alone means nothing. What seems to work is this: For WiFi, check if (flags & kSCNetworkReachabilityFlagsIsDirect). For a plugged-in Internet connection, check if (flags & kSCNetworkReachabilityFlagsIsLocalAddress). Also, when there is no connection at all, the flags for kSCNetworkReachabilityFlagsTransientConnection and kSCNetworkReachabilityFlagsConnectionRequired show up.
2

Apple has a nice code which does it for you. You can check if your connection is WiFi for instnace or just cell/WiFi. link text

answered Jun 8, 2010 at 12:19

3 Comments

Yes, I'm using this for checking the connectivity for iPhone. My question was whether it will work for regular cocoa application either
developer.apple.com/iphone/library/samplecode/Reachability/… says: Runtime Requirements: Mac OS X 10.5.3, iPhone OS 3.0, so my guess is yes.
The sample in this link is for iOS ONLY. This dont compile in OSX. If you look to the code there are "UITextFields" and other 'UI' stuf all over the place. The 'Reachability' class wont work also as @dbainbridge explain in your post.
0

I know this is an old thread but for anyone running into this in 2018, there's an simpler and quicker solution using a Process and the ping command.

Swift 4 example:

func ping(_ host: String) -> Int32 {
 let process = Process.launchedProcess(launchPath: "/sbin/ping", arguments: ["-c1", host])
 process.waitUntilExit()
 return process.terminationStatus
}
let internetAvailable = ping("google.com") == 0
print("internetAvailable \(internetAvailable)")
answered Oct 18, 2018 at 18:16

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.