Как использовать класс доступности для обнаружения действительного интернет-соединения?

Я новичок в разработке iOS и изо всех сил пытаюсь заставить работать классreachability.h. Вот мой код для контроллера представления:

- (void)viewWillAppear:(BOOL)animated
{
    [[NSNotificationCenter defaultCenter]
     addObserver:self 
     selector:@selector(checkNetworkStatus:) 
     name:kReachabilityChangedNotification 
     object:nil];

    internetReachable = [Reachability reachabilityForInternetConnection];
    [internetReachable startNotifier];
}

- (void)checkNetworkStatus:(NSNotification *)notice {
    NetworkStatus internetStatus = [internetReachable currentReachabilityStatus];
    NSLog(@"Network status: %i", internetStatus);
}

Выглядит нормально, но в консоли xcode ничего не появляется при запуске приложения и переключении на это представление.

Я использую Reachability 2.2 и iOS 4.2.

Есть ли что-то очевидное, что я делаю неправильно?


person Camsoft    schedule 04.03.2011    source источник


Ответы (7)


ОТРЕДАКТИРОВАНО: Если вы хотите проверить достижимость перед выполнением некоторого кода, вы должны просто использовать

Reachability *reachability = [Reachability reachabilityForInternetConnection];    
NetworkStatus internetStatus = [reachability currentReachabilityStatus];
if (internetStatus != NotReachable) {
    //my web-dependent code
}
else {
    //there-is-no-connection warning
}

Вы также можете добавить где-нибудь наблюдателя достижимости (например, в viewDidLoad):

Reachability *reachabilityInfo;
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(myReachabilityDidChangedMethod)
                                             name:kReachabilityChangedNotification
                                           object:reachabilityInfo];

Не забудьте вызвать [[NSNotificationCenter defaultCenter] removeObserver:self];, когда вам больше не нужно определение достижимости (например, в методе dealloc).

person knuku    schedule 04.03.2011
comment
Спасибо за это, но я получаю сообщение об ошибке -isReachable не найден. Случайно ли ваш пример для более старой версии достижимости? - person Camsoft; 04.03.2011
comment
Это, вероятно, вызывает большие проблемы. Как насчет VPN-соединений по запросу и других проблемных моментов? - person Proud Member; 29.05.2012
comment
Конечно, это не обязательно, но я не могу представить хорошее приложение, связанное с веб-сервисом, без использования достижимости. - person knuku; 25.01.2013

Вот как я это делаю. У меня есть переменная экземпляра, которую я установил в своем методе инициализации:

_reachability = [[APReachability reachabilityForInternetConnection] retain];

и когда мне нужно запросить статус сети, я делаю:

NetworkStatus networkStatus = [_reachability currentReachabilityStatus];
if (networkStatus != NotReachable) {
    // Network related code
}
else {
    // No network code
}

Если вы заботитесь о Wi-Fi и т. д., статус сети может быть:

    NotReachable // No network
    ReachableViaWiFi // Reachable via Wifi
    ReachableViaWWAN // Reachable via cellular
person codecaffeine    schedule 04.03.2011

Обновление: 4 ноября 2013 г.

Использование версии Reachability 3.0 на iOS7

Чтобы опираться на ответы @NR4TR и @codecaffeine:

Есть 5 способов сделать это (не скомпилировано :)

#include <ifaddrs.h>
#include <arpa/inet.h>

//1 - Is www.apple.com reachable?
Reachability *rHostName = [Reachability reachabilityWithHostName:@"www.apple.com"];
NetworkStatus s1 = [rHostName currentReachabilityStatus];

//2 - Is local wifi router or access point reachable?
Reachability *rLocalWiFi = [Reachability reachabilityForLocalWiFi];
NetworkStatus s2 = [rLocalWiFi currentReachabilityStatus];

//3 - Is my access point connected to a router and the router connected to the internet?
Reachability *rConnection = [Reachability reachabilityForInternetConnection];
NetworkStatus s3 = [rConnection currentReachabilityStatus];

//4  IPv4 standard addresses checking instead of host to avoid dns lookup step
struct sockaddr_in saIPv4;
inet_pton(AF_INET, "74.125.239.51", &(saIPv4.sin_addr));
saIPv4.sin_len = sizeof(saIPv4);
saIPv4.sin_family = AF_INET;
Reachability *rIPv4 = [Reachability reachabilityWithAddress:&saIPv4];
NetworkStatus s4 = [rIPv4 currentReachabilityStatus];

//5  IPv6 addresses checking instead of host to avoid dns lookup step
struct sockaddr_in saIPv6;
inet_pton(AF_INET, "2607:f8b0:4010:801::1014", &(saIPv6.sin_addr));
saIPv6.sin_len = sizeof(saIPv6);
saIPv6.sin_family = AF_INET;
Reachability *rIPv6 = [Reachability reachabilityWithAddress:&saIPv6];
NetworkStatus s5 = [rIPv6 currentReachabilityStatus];

Состояние обработки такое же

if (ReachableViaWiFi == s1)
    return @"WiFi"; //@"WLAN"

if (ReachableViaWWAN == s1)
    return @"Cellular"; //@"WWAN"

return @"None";
person Dickey Singh    schedule 04.11.2013

Перейдите по этой ссылке, она содержит очень полезный исходный код и шаги https://github.com/tonymillion/Reachability. . Это дает вам информацию о том, как вы можете использовать различные методы в Reachability для игры.

Добавьте system.configuration.framewok, а также файлы Reachability.m и Reachability.h в свой проект. там после использования таких методов, как

+(instancetype)reachabilityWithHostName:(NSString*)hostname;
+(instancetype)reachabilityForInternetConnection;
+(instancetype)reachabilityWithAddress:(void *)hostAddress;
+(instancetype)reachabilityForLocalWiFi;

Пример фрагмента:

- (void)CheckConnection
{


    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(reachabilityChanged:) 
                                                 name:kReachabilityChangedNotification 
                                               object:nil];


    Reachability * reach = [Reachability reachabilityWithHostname:@"www.google.com"];

    reach.reachableBlock = ^(Reachability * reachability)
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            _blockLabel.stringValue = @"Block Says Reachable";
        });
    };

    reach.unreachableBlock = ^(Reachability * reachability)
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            _blockLabel.stringValue = @"Block Says Unreachable";
        });
    };

    [reach startNotifier];
}

Надеюсь это поможет

person Sowjanya lankisetty    schedule 10.06.2016

просто импортируйте классы достижимости и после этого

-(BOOL) connectedToNetwork
 {
const char *host_name = "www.google.com";
  BOOL _isDataSourceAvailable = NO;
Boolean success;
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL,host_name);
SCNetworkReachabilityFlags flags;
success = SCNetworkReachabilityGetFlags(reachability, &flags);
_isDataSourceAvailable = success &&
(flags & kSCNetworkFlagsReachable) &&
!(flags & kSCNetworkFlagsConnectionRequired);

CFRelease(reachability);

return _isDataSourceAvailable;
}
person mahesh chowdary    schedule 28.11.2013

См. приведенный ниже код для проверки Internet Connectivity:

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) {
    return 0;
}
BOOL isReachable = flags & kSCNetworkFlagsReachable;
BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;

BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;
NSURL *testURL = [NSURL URLWithString:@"http://www.google.com/"];
NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];

NSURLResponse *response = nil;
NSError *error = nil;

NSData *connectiondata = [NSURLConnection sendSynchronousRequest:testRequest
returningResponse:&response

BOOL connection=NO;

if ([connectiondata length] > 0 &&
error == nil){
    NSLog(@"Connection present” );
    connection=YES;
} else {
    NSLog(@"No Connection" );
    connection=NO;
}

return ((isReachable && !needsConnection) || nonWiFi) ? (connection ? YES : NO) : NO;
person Kiran K    schedule 01.03.2016

Самый простой способ (после того, как вы добавили в свой проект Доступность):

Reachability *reachability = [Reachability reachabilityForInternetConnection];
if (reachability.isReachable) {
    NSLog(@"We have internet!");
} else {
    NSLog(@"No internet!");
}
person Inti    schedule 09.08.2017