我想检查一下我是否可以在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),如果是这样,有什么更好的方法来实现这一点?


当前回答

试试这个:

- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error


if ([self.delegate respondsToSelector:@selector(getErrorResponse:)]) {
    [self.delegate performSelector:@selector(getErrorResponse:) withObject:@"No Network Connection"];
}

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"BMC" message:@"No Network Connection" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK",nil];
[alertView show];

}

其他回答

首先下载reachability类并放入reachability.h和reachability.h。m文件在你的Xcode。

最好的方法是创建一个通用的Functions类(NSObject),这样你就可以在任何类中使用它。这是检查网络连接可达性的两种方法:

+(BOOL) reachabiltyCheck
{
    NSLog(@"reachabiltyCheck");
    BOOL status =YES;
    [[NSNotificationCenter defaultCenter] addObserver:self
                                          selector:@selector(reachabilityChanged:)
                                          name:kReachabilityChangedNotification
                                          object:nil];
    Reachability * reach = [Reachability reachabilityForInternetConnection];
    NSLog(@"status : %d",[reach currentReachabilityStatus]);
    if([reach currentReachabilityStatus]==0)
    {
        status = NO;
        NSLog(@"network not connected");
    }
    reach.reachableBlock = ^(Reachability * reachability)
    {
        dispatch_async(dispatch_get_main_queue(), ^{
        });
    };
    reach.unreachableBlock = ^(Reachability * reachability)
    {
        dispatch_async(dispatch_get_main_queue(), ^{
        });
    };
    [reach startNotifier];
    return status;
}

+(BOOL)reachabilityChanged:(NSNotification*)note
{
    BOOL status =YES;
    NSLog(@"reachabilityChanged");
    Reachability * reach = [note object];
    NetworkStatus netStatus = [reach currentReachabilityStatus];
    switch (netStatus)
    {
        case NotReachable:
            {
                status = NO;
                NSLog(@"Not Reachable");
            }
            break;

        default:
            {
                if (!isSyncingReportPulseFlag)
                {
                    status = YES;
                    isSyncingReportPulseFlag = TRUE;
                    [DatabaseHandler checkForFailedReportStatusAndReSync];
                }
            }
            break;
    }
    return status;
}

+ (BOOL) connectedToNetwork
{
    // Create zero addy
    struct sockaddr_in zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;

    // Recover reachability flags
    SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
    SCNetworkReachabilityFlags flags;
    BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
    CFRelease(defaultRouteReachability);
    if (!didRetrieveFlags)
    {
        NSLog(@"Error. Could not recover network reachability flags");
        return NO;
    }
    BOOL isReachable = flags & kSCNetworkFlagsReachable;
    BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
    BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;
    NSURL *testURL = [NSURL URLWithString:@"http://www.apple.com/"];
    NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL  cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
    NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:self];
    return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO;
}

现在您可以通过调用这个类方法来检查任何类中的网络连接。

Swift 3 / Swift 4

您必须首先导入

import SystemConfiguration

您可以通过以下方法检查Internet连接。

func isConnectedToNetwork() -> Bool {

    var zeroAddress = sockaddr_in()
    zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
    zeroAddress.sin_family = sa_family_t(AF_INET)

    let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
            SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
        }
    }

    var flags = SCNetworkReachabilityFlags()
    if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
        return false
    }
    let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
    let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
    return (isReachable && !needsConnection)
}

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

可达性

这是Swift 3.0和异步的。大多数答案是同步解决方案,这将阻塞你的主线程,如果你有一个非常慢的连接。

这个解决方案更好,但并不完美,因为它依赖于谷歌来检查连接,所以可以随意使用另一个URL。

func checkInternetConnection(completionHandler:@escaping (Bool) -> Void)
{
    if let url = URL(string: "http://www.google.com/")
    {
        var request = URLRequest(url: url)
        request.httpMethod = "HEAD"
        request.cachePolicy = .reloadIgnoringLocalAndRemoteCacheData
        request.timeoutInterval = 5

        let tast = URLSession.shared.dataTask(with: request, completionHandler:
        {
            (data, response, error) in

            completionHandler(error == nil)
        })
        tast.resume()
    }
    else
    {
        completionHandler(true)
    }
}

参见介绍Network.framework: socket的现代替代方案。

我们应该在某些时候摆脱可达性。