Как уже упоминалось другими, достижимость обнаруживает изменения в вашем оборудовании вместо реальной доступности сервера.Прочитав много постов и разбив голову, я придумал этот код.
Вот полная реализация класса ReachabilityManager, который использует Reachability и URLConnection, чтобы убедиться, что соединение доступно или нет.Обратите внимание, что это зависит от классов Reachability (я использую реализацию 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