Разумно ли использовать Reachability для проверки доступности удаленного хоста? - PullRequest
3 голосов
/ 21 января 2011

Разумно ли использовать Reachability Class (от Apple) для проверки доступности удаленного хоста?скажем, например, www.google.com

, или я должен использовать

NSString *connectedString = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com/"]]; 

if ([connectedString length] != 0) // Host Available

, что является лучшим вариантом , так как я слышал, что Достижимостьошибка проверки доступности хоста ?

Ответы [ 6 ]

10 голосов
/ 06 апреля 2011

Вот хороший способ проверить, доступен ли хост:

    NSURLResponse *response=nil;
    NSError *error=nil;
    NSData *data = nil;
    NSURLRequest *request = [NSURLRequest requestWithURL:your_url];

    data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

Если хост не в сети, вы получите код ошибки в error, nil в data и nilв response переменных.
Если хост подключен к сети и ответит, будет несколько response, data и error==nil.

3 голосов
/ 05 марта 2014

Как уже упоминалось другими, достижимость обнаруживает изменения в вашем оборудовании вместо реальной доступности сервера.Прочитав много постов и разбив голову, я придумал этот код.

Вот полная реализация класса 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
3 голосов
/ 16 октября 2011

Достижимость не скажет вам, если удаленный хост является контактным.Он тестирует только первый прыжок, т.е. вы можете отправить пакет на ваш маршрутизатор.Если маршрутизатор не может подключиться к более широкому Интернету, доступность все равно скажет вам, что у вас есть Wi-Fi соединениеВам необходимо внедрить одно из других предложенных решений для проверки «истинной» достижимости.

1 голос
/ 21 января 2011

Желательно сначала проверить, есть ли у вас какое-либо подключение к Интернету, и для этого я использую Reachability.И я пытаюсь установить соединение с сервером только у меня есть интернет.

0 голосов
/ 21 января 2011

Следующий код из developer.apple.com может помочь вам ..

// Create the request.

NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.apple.com/"]

                        cachePolicy:NSURLRequestUseProtocolCachePolicy

                    timeoutInterval:60.0];

// create the connection with the request

// and start loading the data

NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

if (theConnection) {

    // Create the NSMutableData to hold the received data.

    // receivedData is an instance variable declared elsewhere.

    receivedData = [[NSMutableData data] retain];

} else {

    // Inform the user that the connection failed.

}
0 голосов
/ 21 января 2011

Вот руководство по использованию Reachability. http://www.raddonline.com/blogs/geek-journal/iphone-sdk-testing-network-reachability/

NSString *connectedString = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com/"]]; 

if ([connectedString length] != 0) // Host Available

Код, который вы предоставили, также должен работать, но может не дать желаемого результата. Достижимость более надежна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...