Как проверить активное интернет-соединение на iOS или macOS?

1326

Я хотел бы проверить, есть ли у меня подключение к Интернету на iOS с использованием библиотек Cocoa Touch или на macOS с использованием библиотек Cocoa .

Я придумал способ сделать это, используя NSURL. То, как я это сделал, кажется немного ненадежным (потому что даже когда-нибудь даже Google может не работать, а полагаться на третье лицо кажется плохим), и хотя я мог проверить, есть ли ответ от других сайтов, если Google не отвечает, действительно кажется расточительным и ненужными накладными расходами на моем приложении.

- (BOOL) connectedToInternet
{
    NSString *URLString = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]];
    return ( URLString != NULL ) ? YES : NO;
}

Это то, что я сделал плохо (не говоря stringWithContentsOfURLуже об устаревшем в iOS 3.0 и macOS 10.4), и если так, какой лучший способ сделать это?

Брок Вульф
источник
11
Скорее return (BOOL)URLString;или даже лучше, return !!URLStringилиreturn URLString != nil
3
Я не знаю, каков ваш вариант использования, но если вы можете, предпочтительнее попробовать запрос и обработать любые ошибки, такие как отсутствие соединения, которое возникает. Если вы не можете этого сделать, то в этом случае есть много полезных советов.
SK9
2
Ваше решение умное, и я предпочитаю это. Вы также можете использовать, NSString *URLString = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"https://twitter.com/getibox"] encoding:NSUTF8StringEncoding error:nil];чтобы избавиться от раздражающего предупреждения.
Абдельрахман Ид
4
попробуйте использовать класс Reachability по приведенной ниже ссылке, он будет работать для вас github.com/tonymillion/Reachability
Dhaval H. Nena
4
Для тех, кто недавно нашел этот ответ: stackoverflow.com/a/8813279
afollestad

Ответы:

1285

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


стриж

1) Установите через CocoaPods или Карфаген: https://github.com/ashleymills/Reachability.swift

2) Тест достижимости с помощью замыканий

let reachability = Reachability()!

reachability.whenReachable = { reachability in
    if reachability.connection == .wifi {
        print("Reachable via WiFi")
    } else {
        print("Reachable via Cellular")
    }
}

reachability.whenUnreachable = { _ in
    print("Not reachable")
}

do {
    try reachability.startNotifier()
} catch {
    print("Unable to start notifier")
}

Objective-C

1) Добавьте SystemConfigurationфреймворк в проект, но не беспокойтесь о его включении

2) Добавить версию Tony Million Reachability.hи Reachability.mв проект (можно найти здесь: https://github.com/tonymillion/Reachability )

3) Обновление раздела интерфейса

#import "Reachability.h"

// Add this to the interface in the .m file of your view controller
@interface MyViewController ()
{
    Reachability *internetReachableFoo;
}
@end

4) Затем внедрите этот метод в файл .m вашего контроллера представления, который вы можете вызвать

// Checks if we have an internet connection or not
- (void)testInternetConnection
{   
    internetReachableFoo = [Reachability reachabilityWithHostname:@"www.google.com"];

    // Internet is reachable
    internetReachableFoo.reachableBlock = ^(Reachability*reach)
    {
        // Update the UI on the main thread
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"Yayyy, we have the interwebs!");
        });
    };

    // Internet is not reachable
    internetReachableFoo.unreachableBlock = ^(Reachability*reach)
    {
        // Update the UI on the main thread
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"Someone broke the internet :(");
        });
    };

    [internetReachableFoo startNotifier];
}

Важное примечание:Reachability класс является одним из наиболее часто используемых классов в проектах , так что вы можете столкнуться конфликты имен с другими проектами. Если это произойдет, вам придется переименовать одну из пар Reachability.hи Reachability.mфайлов во что-то другое, чтобы решить проблему.

Примечание: домен, который вы используете, не имеет значения. Это просто тестирование шлюза в любой домен.

Меня ограбили
источник
4
@gonzobrains: домен, который вы используете, не имеет значения. Это просто тестирование шлюза в любой домен.
iwasrobbed
3
@KaanDedeoglu Это всего лишь пример, используйте любой домен, который вы хотите. Он просто проверяет наличие шлюза в Интернет, а не то, что домен действительно доступен.
взорван
1
О, кстати, вам нужно добавить SystemConfiguration.frameworkв проект (для метода 1).
мудрый
2
Используйте www.appleiphonecell.com вместо google.com - этот URL был создан Apple именно по этой причине.
Смикей
1
Использование www.appleiphonecell.com в настоящее время (2018) является плохим выбором. Теперь он перенаправляет на Apple.com, который является> 40 КБ HTML-файл. Вернуться на google.com - это всего 11kB. Кстати, google.com/m имеет тот же размер, но, как сообщается, он медленнее на 120 мсек.
BlueskyMed
311

Мне нравится, чтобы все было просто. Я делаю это так:

//Class.h
#import "Reachability.h"
#import <SystemConfiguration/SystemConfiguration.h>

- (BOOL)connected;

//Class.m
- (BOOL)connected
{
    Reachability *reachability = [Reachability reachabilityForInternetConnection];
    NetworkStatus networkStatus = [reachability currentReachabilityStatus];
    return networkStatus != NotReachable;
}

Затем я использую это всякий раз, когда я хочу увидеть, есть ли у меня соединение:

if (![self connected]) {
    // Not connected
} else {
    // Connected. Do some Internet stuff
}

Этот метод не ждет изменения состояния сети, чтобы что-то делать. Он просто проверяет состояние, когда вы просите его.

cannyboy
источник
Привет @msec, вы можете попробовать решение Эндрю Циммера на этой странице, оно отлично работает с отключенным adsl (и подключенным wifi)
Williew
1
Для тех, кто просто копирует и вставляет, как я сделал с приведенным выше кодом. Также добавьте SystemConfiguration.framework вручную, иначе вы получите ошибку компоновки.
Ифтихар Али Ансари
Всегда будь доступным, если я соединяюсь с WiFi. WiFi не означает, что у него есть подключение к интернету. Я хочу проверить подключение к интернету, даже если у него есть подключение к WiFi. Можете ли вы помочь мне?
Уэсли
@wesley Как ты решил это?
Кесельме
146

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

Включите SystemConfiguration.framework в ваш проект.

Сделайте некоторые импортные:

#import <sys/socket.h>
#import <netinet/in.h>
#import <SystemConfiguration/SystemConfiguration.h>

Теперь просто вызовите эту функцию:

/*
Connectivity testing code pulled from Apple's Reachability Example: https://developer.apple.com/library/content/samplecode/Reachability
 */
+(BOOL)hasConnectivity {
    struct sockaddr_in zeroAddress;
    bzero(&zeroAddress, sizeof(zeroAddress));
    zeroAddress.sin_len = sizeof(zeroAddress);
    zeroAddress.sin_family = AF_INET;

    SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)&zeroAddress);
    if (reachability != NULL) {
        //NetworkStatus retVal = NotReachable;
        SCNetworkReachabilityFlags flags;
        if (SCNetworkReachabilityGetFlags(reachability, &flags)) {
            if ((flags & kSCNetworkReachabilityFlagsReachable) == 0)
            {
                // If target host is not reachable
                return NO;
            }

            if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0)
            {
                // If target host is reachable and no connection is required
                //  then we'll assume (for now) that your on Wi-Fi
                return YES;
            }


            if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) ||
                 (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0))
            {
                // ... and the connection is on-demand (or on-traffic) if the
                //     calling application is using the CFSocketStream or higher APIs.

                if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0)
                {
                    // ... and no [user] intervention is needed
                    return YES;
                }
            }

            if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN)
            {
                // ... but WWAN connections are OK if the calling application
                //     is using the CFNetwork (CFSocketStream?) APIs.
                return YES;
            }
        }
    }

    return NO;
}

И это iOS 5 проверено для вас.

Эндрю Циммер
источник
@JezenThomas Это не выполняет интернет-проверку асинхронно, поэтому она «намного тоньше» ... Вы всегда должны делать это асинхронно, подписываясь на уведомления, чтобы не повесить приложение в этом процессе.
взорван
Спасибо, эта работа, даже если вы используете Wi-Fi ADSL и ADSL не подключен, это именно то, что мне нужно.
Williew
5
Это приводит к утечке памяти - структура «читабельность» (объект, вещь) должна быть освобождена с помощью CFRelease ().
Рассел Малл
@RussellMull ... есть идеи, как исправить утечку?
i_raqz
Странно, что этот ответ предшествует моему (на вопрос, помеченный как дубликат) на 2 года, точно так же, как мой, но я никогда не видел его до сегодняшнего дня.
ArtOfWarfare
122

Раньше это был правильный ответ, но теперь он устарел, так как вместо этого вы должны подписаться на уведомления о доступности. Этот метод проверяет синхронно:


Вы можете использовать класс доступности Apple. Это также позволит вам проверить, включен ли Wi-Fi:

Reachability* reachability = [Reachability sharedReachability];
[reachability setHostName:@"www.example.com"];    // Set your host name here
NetworkStatus remoteHostStatus = [reachability remoteHostStatus];

if (remoteHostStatus == NotReachable) { }
else if (remoteHostStatus == ReachableViaWiFiNetwork) { }
else if (remoteHostStatus == ReachableViaCarrierDataNetwork) { }

Класс Reachability поставляется не с SDK, а является частью этого образца приложения Apple . Просто скачайте его и скопируйте Reachability.h / m в ваш проект. Кроме того, вы должны добавить инфраструктуру SystemConfiguration в ваш проект.

Даниэль Ринсер
источник
6
Смотрите мой комментарий выше о том, чтобы не использовать такую ​​доступность. Используйте его в асинхронном режиме и подписывайтесь на уведомления, которые он отправляет - не делайте.
Кендалл Хельмштеттер Гелнер
Этот код является хорошей отправной точкой для вещей, которые вам нужно установить, прежде чем вы сможете использовать методы делегата для класса достижимости.
Брок Вульф
82

Вот очень простой ответ:

NSURL *scriptUrl = [NSURL URLWithString:@"http://www.google.com/m"];
NSData *data = [NSData dataWithContentsOfURL:scriptUrl];
if (data)
    NSLog(@"Device is connected to the Internet");
else
    NSLog(@"Device is not connected to the Internet");

URL должен указывать на очень маленький сайт. Я использую мобильный сайт Google здесь, но если бы у меня был надежный веб-сервер, я бы загрузил небольшой файл с одним символом для максимальной скорости.

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

Осторожно: это ненадолго заблокирует вашу ветку, пока он загружает сайт. В моем случае это не было проблемой, но вы должны рассмотреть это (благодарность Брэду за указание на это).

Erik
источник
10
Мне очень нравится эта идея, но я бы сказал, что для надежности 99,999% при сохранении небольшого размера ответа перейдите на страницу www.google.com/m, которая является мобильным представлением для Google.
2012 года
1
Отличное решение @Erik. Я также рекомендую вам использовать www.google.com вместо www.google.com/m, как сказал rwyland. Это странно, но из моего теста мобильная версия всегда занимает примерно на 120 мс больше, чем www.google.com
Sebyddd
4
Документы Apple рекомендуют не делать этого, так как это может блокировать поток в медленной сети, может привести к прекращению работы приложения в iOS
Брэд Томас,
Спасибо за положительный отзыв, согласитесь, что www.google.com/m является лучшим решением из-за надежности!
Эрик
3
LOL, я уверен, что Google ценит, что вы предлагаете людям использовать их в качестве ресурса для проверки интернета.
mxcl
73

Вот как я это делаю в своих приложениях: хотя код ответа 200 и ничего не гарантирует, он достаточно стабилен для меня. Это не требует такой большой загрузки, как ответы NSData, опубликованные здесь, так как мой просто проверяет ответ HEAD.

Swift Code

func checkInternet(flag:Bool, completionHandler:(internet:Bool) -> Void)
{
    UIApplication.sharedApplication().networkActivityIndicatorVisible = true

    let url = NSURL(string: "http://www.google.com/")
    let request = NSMutableURLRequest(URL: url!)

    request.HTTPMethod = "HEAD"
    request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
    request.timeoutInterval = 10.0

    NSURLConnection.sendAsynchronousRequest(request, queue:NSOperationQueue.mainQueue(), completionHandler:
    {(response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in

        UIApplication.sharedApplication().networkActivityIndicatorVisible = false

        let rsp = response as! NSHTTPURLResponse?

        completionHandler(internet:rsp?.statusCode == 200)
    })
}

func yourMethod()
{
    self.checkInternet(false, completionHandler:
    {(internet:Bool) -> Void in

        if (internet)
        {
            // "Internet" aka Google URL reachable
        }
        else
        {
            // No "Internet" aka Google URL un-reachable
        }
    })
}

Код Objective-C

typedef void(^connection)(BOOL);

- (void)checkInternet:(connection)block
{
    NSURL *url = [NSURL URLWithString:@"http://www.google.com/"];
    NSMutableURLRequest *headRequest = [NSMutableURLRequest requestWithURL:url];
    headRequest.HTTPMethod = @"HEAD";

    NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration ephemeralSessionConfiguration];
    defaultConfigObject.timeoutIntervalForResource = 10.0;
    defaultConfigObject.requestCachePolicy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;

    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue: [NSOperationQueue mainQueue]];

    NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:headRequest
        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
    {
        if (!error && response)
        {
            block([(NSHTTPURLResponse *)response statusCode] == 200);
        }
    }];
    [dataTask resume];
}

- (void)yourMethod
{
    [self checkInternet:^(BOOL internet)
    {
         if (internet)
         {
             // "Internet" aka Google URL reachable
         }
         else
         {
             // No "Internet" aka Google URL un-reachable
         }
    }];
}
klcjr89
источник
3
Похоже, это самый быстрый путь
Павел
3
Внимание: по моему опыту, это решение не работает все время. Во многих случаях ответ возвращается 403, после того, как он потратил сладкое время. Это решение казалось идеальным, но не гарантирует 100% результатов.
Мустафа
10
По состоянию на июнь 2014 года это не получится в материковом Китае из-за того, что правительство Китая теперь полностью блокирует google.com. (google.cn работает, но в материковом Китае нет baidu.com, нет интернета) Вероятно, лучше пинговать любой сервер, с которым вам нужно общаться.
prewett
4
Вместо этого используйте www.appleiphonecell.com - Apple создал этот URL именно по этой причине.
Смикей
1
Я использовал appleiphonecell, так как он принадлежит Apple, его можно использовать и в Китае, и это очень быстрый сайт. Это, в сочетании с вашим ответом, дало мне самое ближайшее и быстрое решение. Спасибо
Септроник
57

Apple предоставляет пример кода для проверки доступности различных типов сети. В качестве альтернативы есть пример в поваренной книге разработчиков iPhone.

Примечание. См. Комментарий @ KHG к этому ответу относительно использования кода доступности Apple.

teabot
источник
Спасибо. Я обнаружил, что документация XCode в 3.0 также содержит исходный код, найденный поиском «достижимости» в документации.
Брок Вульф
7
Обратите внимание, что новая редакция (09-08-09) образца кода Reachability от Apple является асинхронной.
Даниэль Хеппер
46

Вы можете использовать Reachability ( доступно здесь ).

#import "Reachability.h"

- (BOOL)networkConnection {
    return [[Reachability reachabilityWithHostName:@"www.google.com"] currentReachabilityStatus];
}

if ([self networkConnection] == NotReachable) { /* No Network */ } else { /* Network */ } //Use ReachableViaWiFi / ReachableViaWWAN to get the type of connection.
Александр Азизи
источник
@Supertecnoboff Нет, это асинхронно.
Александр Азизи
39

Apple предоставляет пример приложения, которое делает именно это:

достижимость

NANNAV
источник
7
Следует отметить, что образец Reachability обнаруживает только то, какие интерфейсы активны, но не какие из них имеют действительное подключение к Интернету. Приложения должны корректно обрабатывать ошибки, даже когда Reachability сообщает, что все готово к работе.
rpetrich
К счастью, в 3.0 ситуация намного лучше, так как система предоставит страницу входа для пользователей за заблокированным WiFi, где вы должны войти в систему, чтобы использовать ... вы используете для проверки перенаправления вручную (и вы все еще делаете если разрабатывает приложения 2.2.1)
Кендалл Хельмштеттер Гелнер
Я бы не сказал, что приложение Reachability делает именно то, что требуется. Однако это хорошая отправная точка для добавления
Йохан Карлссон,
Неработающая ссылка !, буду признателен, если это можно будет проверить / исправить, большое спасибо
Хейдер Сати
33

Только класс Reachability был обновлен. Теперь вы можете использовать:

Reachability* reachability = [Reachability reachabilityWithHostName:@"www.apple.com"];
NetworkStatus remoteHostStatus = [reachability currentReachabilityStatus];

if (remoteHostStatus == NotReachable) { NSLog(@"not reachable");}
else if (remoteHostStatus == ReachableViaWWAN) { NSLog(@"reachable via wwan");}
else if (remoteHostStatus == ReachableViaWiFi) { NSLog(@"reachable via wifi");}
Бен Гроот
источник
1
Если с момента выпуска 4.0 что-то не изменилось, этот код не является асинхронным, и вы гарантированно увидите его в отчетах о сбоях - это случилось со мной раньше.
бпапа
1
Я согласен с бпапа. Это не очень хорошая идея использовать синхронный код. Спасибо за информацию, хотя
Брок Вульф
22

Если вы используете, AFNetworkingвы можете использовать его собственную реализацию для статуса доступности интернета.

Лучший способ использовать AFNetworkingэто подклассAFHTTPClient класса и использовать этот класс для сетевых подключений.

Одним из преимуществ использования этого подхода является то, что вы можете использовать его blocksдля установки желаемого поведения при изменении состояния достижимости. Предположим, что я создал одноэлементный подкласс с AFHTTPClientименем (как сказано в «Примечаниях по подклассам» в документах AFNetworking ) BKHTTPClient, я бы сделал что-то вроде:

BKHTTPClient *httpClient = [BKHTTPClient sharedClient];
[httpClient setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status)
{
    if (status == AFNetworkReachabilityStatusNotReachable) 
    {
    // Not reachable
    }
    else
    {
        // Reachable
    }
}];

Можно также проверить соединения Wi-Fi или WLAN с помощью специально AFNetworkReachabilityStatusReachableViaWWANи AFNetworkReachabilityStatusReachableViaWiFiперечислений ( подробнее здесь ).

Бруно Кога
источник
18

Я использовал код в этом обсуждении , и он, кажется, работает нормально (прочитайте всю ветку!).

Я не проверял это исчерпывающе с каждым мыслимым типом соединения (например, Wi-Fi ad hoc).

Felixyz
источник
этот код не совсем хорош, потому что он просто проверяет, есть ли у вас Wi-Fi-соединение с маршрутизатором, а не доступ к сети. Вы можете включить Wi-Fi и продолжить доступ к Интернету.
DuckDucking
15

Очень просто .... Попробуйте эти шаги:

Шаг 1: Добавьте SystemConfigurationфреймворк в ваш проект.


Шаг 2: импортируйте следующий код в ваш headerфайл.

#import <SystemConfiguration/SystemConfiguration.h>

Шаг 3: Используйте следующий метод

  • Тип 1:

    - (BOOL) currentNetworkStatus {
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        BOOL connected;
        BOOL isConnected;
        const char *host = "www.apple.com";
        SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, host);
        SCNetworkReachabilityFlags flags;
        connected = SCNetworkReachabilityGetFlags(reachability, &flags);
        isConnected = NO;
        isConnected = connected && (flags & kSCNetworkFlagsReachable) && !(flags & kSCNetworkFlagsConnectionRequired);
        CFRelease(reachability);
        return isConnected;
    }

  • Тип 2:

    Заголовок импорта :#import "Reachability.h"

    - (BOOL)currentNetworkStatus
    {
        Reachability *reachability = [Reachability reachabilityForInternetConnection];
        NetworkStatus networkStatus = [reachability currentReachabilityStatus];
        return networkStatus != NotReachable;
    }

Шаг 4: Как использовать:

- (void)CheckInternet
{
    BOOL network = [self currentNetworkStatus];
    if (network)
    {
        NSLog(@"Network Available");
    }
    else
    {
        NSLog(@"No Network Available");
    }
}
Раджеш Логанатхан
источник
Является ли тип 1 асинхронным?
Supertecnoboff
Я хочу исправления типа 2 из вашего ответа. Я добавил классы достижимости и попытался проверить проверку соединения, используя приведенный выше ваш ответ. он всегда доступен, даже если я подключаюсь по WiFi, но у него нет подключения к интернету. WiFi не означает, что у него есть подключение к интернету. Я хочу проверить подключение к интернету, даже если у него есть подключение к WiFi. Можете ли вы помочь мне?
Уэсли
12
-(void)newtworkType {

 NSArray *subviews = [[[[UIApplication sharedApplication] valueForKey:@"statusBar"] valueForKey:@"foregroundView"]subviews];
NSNumber *dataNetworkItemView = nil;

for (id subview in subviews) {
    if([subview isKindOfClass:[NSClassFromString(@"UIStatusBarDataNetworkItemView") class]]) {
        dataNetworkItemView = subview;
        break;
    }
}


switch ([[dataNetworkItemView valueForKey:@"dataNetworkType"]integerValue]) {
    case 0:
        NSLog(@"No wifi or cellular");
        break;

    case 1:
        NSLog(@"2G");
        break;

    case 2:
        NSLog(@"3G");
        break;

    case 3:
        NSLog(@"4G");
        break;

    case 4:
        NSLog(@"LTE");
        break;

    case 5:
        NSLog(@"Wifi");
        break;


    default:
        break;
}
}
Mutawe
источник
7
Даже если устройство подключено к Wi-Fi или сети другого типа, подключение к Интернету все еще может быть недоступно. Простой тест: подключитесь к домашней сети Wi-Fi, а затем отключите кабельный модем. Все еще подключен к Wi-Fi, но без интернета.
помечен
11
- (void)viewWillAppear:(BOOL)animated
{
    NSString *URL = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]];

    return (URL != NULL ) ? YES : NO;
}

Или используйте класс Reachability .

Есть два способа проверить доступность Интернета с помощью iPhone SDK:

1. Убедитесь, что страница Google открыта или нет.

2. Класс достижимости

Для получения дополнительной информации, пожалуйста, обратитесь к Reachability (Apple Developer).

IOS Rocks
источник
1
Есть два способа проверить доступность интернета в iPhone SDK 1) Проверить, открыта страница Google или нет.
IOS Rocks
1
-1: это синхронный метод, который блокирует основной поток (тот, на котором изменен пользовательский интерфейс приложения), когда он пытается подключиться к google.com. Если у вашего пользователя очень медленное соединение для передачи данных, телефон будет действовать так, как будто процесс не отвечает.
разбит
10

Первое : добавить CFNetwork.frameworkв рамки

Код :ViewController.m

#import "Reachability.h"

- (void)viewWillAppear:(BOOL)animated
{
    Reachability *r = [Reachability reachabilityWithHostName:@"www.google.com"];
    NetworkStatus internetStatus = [r currentReachabilityStatus];

    if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN))
    {
        /// Create an alert if connection doesn't work
        UIAlertView *myAlert = [[UIAlertView alloc]initWithTitle:@"No Internet Connection"   message:NSLocalizedString(@"InternetMessage", nil)delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
        [myAlert show];
        [myAlert release];
    }
    else
    {
         NSLog(@"INTERNET IS CONNECT");
    }
}
Пареш Хирпара
источник
8

Сначала загрузите класс досягаемости и поместите файл reachability.h и reachabilty.m в свой Xcode .

Лучший способ - создать общий класс функций (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;
}

Теперь вы можете проверить сетевое соединение в любом классе, вызвав этот метод класса.

Латика Тивари
источник
8

Существует также другой способ проверки интернет-соединения с помощью iPhone SDK.

Попробуйте реализовать следующий код для сетевого подключения.

#import <SystemConfiguration/SystemConfiguration.h>
#include <netdb.h>

/**
     Checking for network availability. It returns
     YES if the network is available.
*/
+ (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)
    {
        printf("Error. Could not recover network reachability flags\n");
        return NO;
    }

    BOOL isReachable = ((flags & kSCNetworkFlagsReachable) != 0);
    BOOL needsConnection = ((flags & kSCNetworkFlagsConnectionRequired) != 0);

    return (isReachable && !needsConnection) ? YES : NO;
}
Сахил Махаджан
источник
8
  1. Загрузите файл Reachability, https://gist.github.com/darkseed/1182373

  2. И добавить CFNetwork.frameworkи 'SystemConfiguration.framework' в рамках

  3. Сделайте #import "Reachability.h"


Первое : добавить CFNetwork.frameworkв рамки

Код :ViewController.m

- (void)viewWillAppear:(BOOL)animated
{
    Reachability *r = [Reachability reachabilityWithHostName:@"www.google.com"];
    NetworkStatus internetStatus = [r currentReachabilityStatus];

    if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN))
    {
        /// Create an alert if connection doesn't work
        UIAlertView *myAlert = [[UIAlertView alloc]initWithTitle:@"No Internet Connection"   message:NSLocalizedString(@"InternetMessage", nil)delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
        [myAlert show];
        [myAlert release];
    }
    else
    {
         NSLog(@"INTERNET IS CONNECT");
    }
}
Маулик Салви
источник
8

Свифт 3 / Свифт 4

Вы должны сначала импортировать

import SystemConfiguration

Вы можете проверить интернет-соединение следующим способом

func isConnectedToNetwork() -> Bool {

    var zeroAddress = sockaddr_in()
    zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
    zeroAddress.sin_family = sa_family_t(AF_INET)

    let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
            SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
        }
    }

    var flags = SCNetworkReachabilityFlags()
    if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
        return false
    }
    let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
    let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
    return (isReachable && !needsConnection)

}
Деванг Тандель
источник
7

Класс Reachability в порядке, чтобы узнать, доступно ли подключение к Интернету для устройства или нет ...

Но в случае доступа к ресурсу интрасети :

Проверка связи с сервером интрасети с помощью класса достижимости всегда возвращает значение true.

Таким образом, быстрым решением в этом сценарии будет создание веб-метода, вызываемого pingmeвместе с другими веб-методами в службе. pingmeДолжен вернуть что - то.

Поэтому я написал следующий метод для общих функций

-(BOOL)PingServiceServer
{
    NSURL *url=[NSURL URLWithString:@"http://www.serveraddress/service.asmx/Ping"];

    NSMutableURLRequest *urlReq=[NSMutableURLRequest requestWithURL:url];

    [urlReq setTimeoutInterval:10];

    NSURLResponse *response;

    NSError *error = nil;

    NSData *receivedData = [NSURLConnection sendSynchronousRequest:urlReq
                                                 returningResponse:&response
                                                             error:&error];
    NSLog(@"receivedData:%@",receivedData);

    if (receivedData !=nil)
    {
        return YES;
    }
    else
    {
        NSLog(@"Data is null");
        return NO;
    }
}

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

Durai Amuthan.H
источник
7

Сделать это самостоятельно очень просто. Следующий метод будет работать. Только убедитесь, что вы не разрешаете передавать имя хоста, такое как HTTP, HTTPS и т. Д.

-(BOOL)hasInternetConnection:(NSString*)urlAddress
{
    SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [urlAddress UTF8String]);
    SCNetworkReachabilityFlags flags;
    if (!SCNetworkReachabilityGetFlags(ref, &flags))
    {
        return NO;
    }
    return flags & kSCNetworkReachabilityFlagsReachable;
}

Это быстро, просто и безболезненно.

Тони
источник
7

Я думаю, что это лучший ответ.

«Да» означает «подключен». «Нет» означает «отключен».

#import "Reachability.h"

 - (BOOL)canAccessInternet
{
    Reachability *IsReachable = [Reachability reachabilityForInternetConnection];
    NetworkStatus internetStats = [IsReachable currentReachabilityStatus];

    if (internetStats == NotReachable)
    {
        return NO;
    }
    else
    {
        return YES;
    }
}
Мина Фаузи
источник
6

Импортируйте Reachable.hкласс в свой ViewControllerи используйте следующий код для проверки подключения :

     #define hasInternetConnection [[Reachability reachabilityForInternetConnection] isReachable]
     if (hasInternetConnection){
           // To-do block
     }
Химаншу Махаджан
источник
Ваш ответ именно то, что я ищу. Вы, сэр, заслуживаете голоса до xD
Никель Артета
Не работает, если вы подключены к WiFi без интернета.
Кесельме
6
  • Шаг 1: Добавьте класс Reachability в свой проект.
  • Шаг 2. Импортируйте класс Reachability
  • Шаг 3: Создайте функцию ниже

    - (BOOL)checkNetConnection {
        self.internetReachability = [Reachability reachabilityForInternetConnection];
        [self.internetReachability startNotifier];
        NetworkStatus netStatus = [self.internetReachability currentReachabilityStatus];
        switch (netStatus) {
            case NotReachable:
            {
                return NO;
            }
    
            case ReachableViaWWAN:
            {
                 return YES;
            }
    
            case ReachableViaWiFi:
            {
                 return YES;
            }
        }
    }
  • Шаг 4: Вызовите функцию, как показано ниже:

    if (![self checkNetConnection]) {
        [GlobalFunctions showAlert:@""
                         message:@"Please connect to the Internet!"
                         canBtntitle:nil
                         otherBtnTitle:@"Ok"];
        return;
    }
    else
    {
        Log.v("internet is connected","ok");
    }
Anny
источник
В документации Apple говорится, что это примечание: Reachability не может сообщить вашему приложению, можете ли вы подключиться к определенному хосту, только о том, что доступен интерфейс, который может разрешить подключение, и о том, является ли этот интерфейс WWAN.
noobsmcgoobs