我想检查一下我是否可以在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()
    }
}

其他回答

Apple提供了示例代码来检查不同类型的网络可用性。在iPhone开发者的烹饪书中也有一个例子。

注:请参阅@KHG关于使用苹果可达代码的回答的评论。

如果你正在使用AFNetworking,你可以使用它自己的实现internet可达状态。

使用AFNetworking的最好方法是子类化AFHTTPClient类,并使用这个类来进行网络连接。

使用这种方法的优点之一是,当可达性状态发生变化时,您可以使用块来设置所需的行为。假设我已经创建了一个名为BKHTTPClient的AFHTTPClient的单例子类(如AFNetworking文档上的“子类注释”所述),我会做如下的事情:

BKHTTPClient *httpClient = [BKHTTPClient sharedClient];
[httpClient setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status)
{
    if (status == AFNetworkReachabilityStatusNotReachable) 
    {
    // Not reachable
    }
    else
    {
        // Reachable
    }
}];

您还可以使用AFNetworkReachabilityStatusReachableViaWWAN和AFNetworkReachabilityStatusReachableViaWiFi枚举来检查Wi-Fi或WLAN连接。

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

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

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

我认为这是最好的答案。

“是”意味着有联系。“No”表示断开连接。

#import "Reachability.h"

 - (BOOL)canAccessInternet
{
    Reachability *IsReachable = [Reachability reachabilityForInternetConnection];
    NetworkStatus internetStats = [IsReachable currentReachabilityStatus];

    if (internetStats == NotReachable)
    {
        return NO;
    }
    else
    {
        return YES;
    }
}

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

可达性