我想检查一下我是否可以在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),如果是这样,有什么更好的方法来实现这一点?
如果你正在使用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连接。
检查Internet连接的可用性(iOS) Xcode 8, Swift 3.0
这是一个简单的方法来检查网络可用性,如我们的设备是否连接到任何网络。我已经成功地将其翻译为Swift 3.0,这里是最终的代码。现有的Apple Reachability类和其他第三方库似乎太复杂了,无法翻译到Swift中。
这适用于3G、4G和WiFi连接。
不要忘记在你的项目构建器中添加“SystemConfiguration.framework”。
//Create new swift class file Reachability in your project.
import SystemConfiguration
public class InternetReachability {
class func isConnectedToNetwork() -> Bool {
var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(&zeroAddress) {
SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0)).takeRetainedValue()
}
var flags: SCNetworkReachabilityFlags = 0
if SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) == 0 {
return false
}
let isReachable = (flags & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
return isReachable && !needsConnection
}
}
// Check network connectivity from anywhere in project by using this code.
if InternetReachability.isConnectedToNetwork() == true {
print("Internet connection OK")
} else {
print("Internet connection FAILED")
}
首先下载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.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)
}
}