我想检查一下我是否可以在iOS上使用Cocoa Touch库或在macOS上使用Cocoa库连接互联网。

我想出了一个方法来做这个使用NSURL。我的方法似乎有点不可靠(因为即使谷歌也可能有一天宕机,依赖第三方似乎很糟糕),虽然如果谷歌没有响应,我可以检查其他一些网站的响应,但这似乎是浪费和不必要的应用程序开销。

- (BOOL)connectedToInternet {
    NSString *URLString = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]];
    return ( URLString != NULL ) ? YES : NO;
}

是我做得不好,(更不用说stringWithContentsOfURL已弃用在iOS 3.0和macOS 10.4),如果是这样,有什么更好的方法来实现这一点?


当前回答

当使用iOS 12或macOS v10.14 (Mojave)或更新版本时,您可以使用NWPathMonitor而不是史前可达性类。作为奖励,你可以很容易地检测到当前的网络连接类型:

import Network // Put this on top of your class

let monitor = NWPathMonitor()

monitor.pathUpdateHandler = { path in
    if path.status != .satisfied {
        // Not connected
    }
    else if path.usesInterfaceType(.cellular) {
        // Cellular 3/4/5g connection
    }
    else if path.usesInterfaceType(.wifi) {
        // Wi-Fi connection
    }
    else if path.usesInterfaceType(.wiredEthernet) {
        // Ethernet connection
    }
}

monitor.start(queue: DispatchQueue.global(qos: .background))

更多信息请访问:https://developer.apple.com/documentation/network/nwpathmonitor

其他回答

下载Reachability文件,https://gist.github.com/darkseed/1182373 在framework中添加CFNetwork.framework和'SystemConfiguration.framework' 导入“Reachability.h”

首先:在framework中添加CFNetwork.framework

代码:ViewController.m

- (void)viewWillAppear:(BOOL)animated
{
    Reachability *r = [Reachability reachabilityWithHostName:@"www.google.com"];
    NetworkStatus internetStatus = [r currentReachabilityStatus];

    if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN))
    {
        /// Create an alert if connection doesn't work
        UIAlertView *myAlert = [[UIAlertView alloc]initWithTitle:@"No Internet Connection"   message:NSLocalizedString(@"InternetMessage", nil)delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
        [myAlert show];
        [myAlert release];
    }
    else
    {
         NSLog(@"INTERNET IS CONNECT");
    }
}

苹果提供了一个示例应用程序,它正是这样做的:

可达性

Reachability类可以确定一个设备的互联网连接是否可用…

但在访问内网资源时:

使用可达性类ping内网服务器总是返回true。

因此,在这种情况下,一个快速的解决方案是创建一个名为pingme的web方法以及服务上的其他web方法。 pingme应该返回一些东西。

所以我写了下面关于普通函数的方法

-(BOOL)PingServiceServer
{
    NSURL *url=[NSURL URLWithString:@"http://www.serveraddress/service.asmx/Ping"];

    NSMutableURLRequest *urlReq=[NSMutableURLRequest requestWithURL:url];

    [urlReq setTimeoutInterval:10];

    NSURLResponse *response;

    NSError *error = nil;

    NSData *receivedData = [NSURLConnection sendSynchronousRequest:urlReq
                                                 returningResponse:&response
                                                             error:&error];
    NSLog(@"receivedData:%@",receivedData);

    if (receivedData !=nil)
    {
        return YES;
    }
    else
    {
        NSLog(@"Data is null");
        return NO;
    }
}

上面的方法对我来说非常有用,所以每当我试图向服务器发送一些数据时,我总是使用这个低超时URLRequest检查我的内部网资源的可达性。

很简单的…试试下面这些步骤:

步骤1:将SystemConfiguration框架添加到项目中。


步骤2:将以下代码导入到头文件中。

#import <SystemConfiguration/SystemConfiguration.h>

第三步:使用以下方法

类型1: - (BOOL) currentNetworkStatus { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; BOOL连接; BOOL与; Const char *host = "www.apple.com"; SCNetworkReachabilityRef reachabilityreachabilitycreatewithname (NULL, host); SCNetworkReachabilityFlags旗帜; connected = SCNetworkReachabilityGetFlags(可达性,&flags); isConnected = NO; isConnected = connected && (flags & kSCNetworkFlagsReachable) && !(flags & kSCNetworkFlagsConnectionRequired); CFRelease(可达性); 返回与; }


类型2: 导入头文件:# Import "Reachability.h" (保龄球)currentNetworkStatus { 可达性*可达性=[互联网连接的可达性]; NetworkStatus NetworkStatus =[可达性currentReachabilityStatus]; 返回networkStatus !=不可访问; }


第四步:使用方法:

- (void)CheckInternet
{
    BOOL network = [self currentNetworkStatus];
    if (network)
    {
        NSLog(@"Network Available");
    }
    else
    {
        NSLog(@"No Network Available");
    }
}

在ViewController中导入Reachable.h类,并使用以下代码检查连通性:

#define hasInternetConnection [[Reachability reachabilityForInternetConnection] isReachable]
if (hasInternetConnection){
      // To-do block
}