正如其他人所提到的,可达性检测硬件的变化,而不是服务器的实际可用性。在阅读了很多帖子之后,我想出了这个代码。
这是 ReachabilityManager 类的完整实现,它使用 Reachability 和 URLConnection 来确保连接可用或不可用。请注意,这取决于可达性类(我使用的是 Tony Million 实现,但我确信它适用于 Apple 类)
如果您在模拟器中对此进行测试并启用/禁用无线连接,您将看到它检测到(有时需要几秒钟)连接/断开连接。以前只有可达性类的东西不起作用。
我还为您的其余代码添加了一些通知,这些通知比 Reachability 中的通知更有效。您可能希望以不同的方式处理此问题。
此外,这是一个单例,因此您可以从任何地方实例化。您可以将其转换为非静态类并从 AppDelegate 实例化它。
如果读者有时间为它创建一些单元测试,请告诉我,这样我们就可以分享更多关于可达性的知识。
只需创建一个新的 NSObject 类并复制以下内容:
。H
#import <Foundation/Foundation.h>
@interface ReachabilityManager : NSObject
+ (void)startReachabilityWithHost : (NSURL *)hostName;
@end
.m
#import "ReachabilityManager.h"
#import "Reachability.h"
@implementation ReachabilityManager
static ReachabilityManager *_sharedReachabilityManager;
static Reachability *reachability;
static NSURL *_hostName;
static BOOL isServerReachable;
+ (void)initialize
{
static BOOL initialized = NO;
if(!initialized)
{
initialized = YES;
_sharedReachabilityManager = [[ReachabilityManager alloc] init];
}
}
+ (void)startReachabilityWithHost : (NSURL *)hostName{
_hostName = hostName;
reachability = [Reachability reachabilityWithHostname:hostName.host];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reachabilityChanged:)
name:kReachabilityChangedNotification
object:nil];
[reachability startNotifier];
}
+ (void)stopReachability{
[reachability stopNotifier];
[[NSNotificationCenter defaultCenter]removeObserver:kReachabilityChangedNotification];
}
+(void)reachabilityChanged: (NSNotification *)notification{
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
BOOL isServerCurrentlyReachable = NO;
do{
isServerCurrentlyReachable = [self checkConnectivityToServer];
BOOL wasServerPreviouslyReachable = isServerReachable;
isServerReachable = isServerCurrentlyReachable;
if (NO == wasServerPreviouslyReachable && YES == isServerCurrentlyReachable)
{
NSLog(@"REACHABLE!");
[[NSNotificationCenter defaultCenter]postNotificationName:@"kNetworkReachabilityCustom" object:[NSNumber numberWithBool:YES]];
}
else if (YES == wasServerPreviouslyReachable && NO == isServerCurrentlyReachable)
{
NSLog(@"UNREACHABLE!");
[[NSNotificationCenter defaultCenter]postNotificationName:@"kNetworkReachabilityCustom" object:[NSNumber numberWithBool:NO]];
}
[NSThread sleepForTimeInterval:5.0];
}while(!isServerCurrentlyReachable);
});
}
+(BOOL)checkConnectivityToServer{
NSURLResponse *response;
NSError *error=nil;
NSData *data = nil;
NSURLRequest *request = [NSURLRequest requestWithURL:_hostName];
data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
return (data && response);
}
@end