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


当前回答

//
//  Connectivity.swift
// 
//
//  Created by Kausik Jati on 17/07/20.
// 
//

import Foundation
import Network

enum ConnectionState: String {
    case notConnected = "Internet connection not avalable"
    case connected = "Internet connection avalable"
    case slowConnection = "Internet connection poor"
}
protocol ConnectivityDelegate: class {
    func checkInternetConnection(_ state: ConnectionState, isLowDataMode: Bool)
}
class Connectivity: NSObject {
    private let monitor = NWPathMonitor()
    weak var delegate: ConnectivityDelegate? = nil
    private let queue = DispatchQueue.global(qos: .background)
    private var isLowDataMode = false
    static let instance = Connectivity()
private override init() {
    super.init()
    monitor.start(queue: queue)
    startMonitorNetwork()
}
private func startMonitorNetwork() {
    monitor.pathUpdateHandler = { path in
        if #available(iOS 13.0, *) {
            self.isLowDataMode = path.isConstrained
        } else {
            // Fallback on earlier versions
            self.isLowDataMode = false
        }
        
        if path.status == .requiresConnection {
            print("requiresConnection")
                self.delegate?.checkInternetConnection(.slowConnection, isLowDataMode: self.isLowDataMode)
        } else if path.status == .satisfied {
            print("satisfied")
                 self.delegate?.checkInternetConnection(.connected, isLowDataMode: self.isLowDataMode)
        } else if path.status == .unsatisfied {
            print("unsatisfied")
                self.delegate?.checkInternetConnection(.notConnected, isLowDataMode: self.isLowDataMode)
            }
        }
    
    }
    func stopMonitorNetwork() {
        monitor.cancel()
    }
}

其他回答

自己做这件事非常简单。下面的方法是可行的。只是要确保不允许将主机名协议(如HTTP、HTTPS等)与名称一起传入。

-(BOOL)hasInternetConnection:(NSString*)urlAddress
{
    SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [urlAddress UTF8String]);
    SCNetworkReachabilityFlags flags;
    if (!SCNetworkReachabilityGetFlags(ref, &flags))
    {
        return NO;
    }
    return flags & kSCNetworkReachabilityFlagsReachable;
}

这是快速、简单和无痛的。

下载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检查我的内部网资源的可达性。

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

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

试试这个:

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

}