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,079
  • 5
  • 63
  • 167
Nava Carmon
  • 4,523
  • 3
  • 40
  • 74
  • 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`. – ArtOfWarfare May 12 '13 at 04:02

5 Answers5

19

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,461
  • 5
  • 90
  • 86
dbainbridge
  • 1,190
  • 11
  • 18
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

Unicorn
  • 2,382
  • 6
  • 29
  • 42
  • This will work for cocoa. For iphone you might have replace the flags and method name based on SDK documentation. – Unicorn Jun 08 '10 at 09:25
  • This function is deprecated, see my answer for the equivalent solution proposed by Apple. – Paul N May 11 '12 at 16:14
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
  • 57,263
  • 20
  • 190
  • 175
Paul N
  • 1,901
  • 1
  • 22
  • 32
  • 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. – ArtOfWarfare May 09 '13 at 13:41
  • 2
    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. – Wienke Aug 21 '13 at 18:57
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

krzyspmac
  • 605
  • 3
  • 6
  • 2
    Yes, I'm using this for checking the connectivity for iPhone. My question was whether it will work for regular cocoa application either – Nava Carmon Jun 08 '10 at 15:56
  • http://developer.apple.com/iphone/library/samplecode/Reachability/Introduction/Intro.html says: Runtime Requirements: Mac OS X 10.5.3, iPhone OS 3.0, so my guess is yes. – krzyspmac Jun 09 '10 at 10:02
  • 1
    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. – Bruno Berisso Aug 31 '11 at 13:26
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)")
Alejandro Cotilla
  • 2,501
  • 1
  • 20
  • 35