在Cocoa应用中检查网络连接

15

我该如何在OS X Cocoa应用程序中检查互联网连接?是否可以重用苹果的iOS可达性示例代码来实现此目的?

谢谢,

Nava


这不是一个特别好的解决方案,这就是为什么我将其列为评论而不是答案,但如果您设置了WebViewframeLoadDelegate,它将在出现provisionalLoadError时接收到通知,如果没有网络连接,这几乎是立即发生的。由于我已经在使用WebView(来自WebKit.framework),所以只要它收到provisionalLoadError,我就会立即弹出错误消息。 - ArtOfWarfare
5个回答

19

目前在苹果网站上列出的 Reachability 代码(2.2版),并且上面提到的代码不能直接在 Mac OS X Cocoa 应用程序中编译。常量 kSCNetworkReachabilityFlagsIsWWAN 只有在编译 TARGET_OS_IPHONE 时才可用,而 Reachability.m 引用了该常量。您需要对 Reachability.m 中引用该常量的两个位置进行 #ifdef 操作,如下所示:

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

#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

这正是我正在寻找的。 - fnc12
1
@dbainbridge,你需要使用'-'而不是0 - craig65535

10

这段代码将帮助你判断互联网是否可达:

-(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;
}

要获取更多信息,您可以查看iPhone可达性


这将适用于Cocoa。 对于iPhone,您可能需要根据SDK文档替换标志和方法名称。 - Unicorn
此函数已被弃用,请参考苹果提出的等效解决方案。 - Paul N

7

独角兽的解决方案已经过时,但您可以使用以下代码获得等效的结果:

SCNetworkReachabilityRef target;

SCNetworkConnectionFlags flags = 0;

Boolean ok;

target = SCNetworkReachabilityCreateWithName(NULL, hostName);

ok = SCNetworkReachabilityGetFlags(target, &flags);

CFRelease(target);

这需要哪些框架?我的应用程序中只包含了 Cocoa 和 WebKit 框架,无法编译它。 - ArtOfWarfare
2
一旦获取了标识:在我的Mac上,即使关闭了Airport并且没有直接连接,标识仍然显示kSCNetworkReachabilityFlagsReachable - 仅仅是“可达性”标志并没有任何作用。看起来有效的是这样做:对于WiFi,请检查(flags & kSCNetworkReachabilityFlagsIsDirect)。对于插入式互联网连接,请检查(flags & kSCNetworkReachabilityFlagsIsLocalAddress)。此外,当根本没有连接时,kSCNetworkReachabilityFlagsTransientConnectionkSCNetworkReachabilityFlagsConnectionRequired的标识会显示出来。 - Wienke

2

苹果有一个很好的代码可以为您完成此操作。您可以检查您的连接是WiFi还是仅限于手机/WiFi。 链接文本


2
是的,我正在使用它来检查iPhone的连接性。我的问题是它是否也适用于常规Cocoa应用程序。 - Nava Carmon
http://developer.apple.com/iphone/library/samplecode/Reachability/Introduction/Intro.html 上说:运行要求:Mac OS X 10.5.3,iPhone OS 3.0,所以我猜是可以的。 - krzyspmac
1
此链接中的示例仅适用于iOS。 在OSX中无法编译。 如果您查看代码,就会发现到处都是“UITextFields”和其他“UI”内容。 “Reachability”类也不起作用,正如@dbainbridge在他的帖子中解释的那样。 - Bruno Berisso

0

我知道这是一个旧的帖子,但对于在2018年遇到此问题的任何人,使用Processping命令有一个更简单和更快速的解决方案。

Swift 4示例:

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)")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接