Як перевірити наявність активного підключення до Інтернету на iOS чи macOS?


1324

Я хотів би перевірити, чи є у мене підключення до Інтернету на iOS за допомогою бібліотек Cocoa Touch або на macOS, що використовує бібліотеки какао .

Я придумав спосіб це зробити за допомогою 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

Відповіді:


1284

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


Швидкий

1) Встановити через CocoaPods або Carthage: 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")
}

Ціль-С

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

2) Додайте версію Reachability.hта Reachability.mпроект до Tony Million (знайдено тут: 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 Це просто приклад, використовуйте будь-який домен, який ви хочете. Він просто перевіряє наявність шлюзу в Інтернеті, а не те, що домен насправді доступний.
iwasrobbed

1
О, btw вам також потрібно додати SystemConfiguration.frameworkдо проекту (для методу 1).
Мудрінді

2
Використовуйте www.appleiphonecell.com замість google.com - цю URL-адресу компанія Apple створила саме з цієї причини.
Smikey

1
Використання www.appleiphonecell.com зараз (2018) - поганий вибір. Тепер він переспрямовує на Apple.com, який є html-файлом> 40 кБ. Назад до google.com - це лише 11 КБ. BTW google.com/m однакового розміру, але, як повідомляється, повільніше на 120 мсек.
BlueskyMed

310

Мені подобається все просто. Я це роблю:

//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
}

Цей метод не чекає змінених статусів мережі для того, щоб виконувати завдання. Він просто перевіряє стан, коли ви його просите.


Привіт @msec, ви можете спробувати рішення Ендрю Циммера на цій сторінці, воно прекрасно спрацьовує з відключеним ADSL (і підключений Wi-Fi)
Williew

1
Для тих, хто просто копіює та вставляє, як я робив із вищевказаним кодом. Також додайте SystemConfiguration.framework вручну, інакше ви отримаєте помилку посилання.
Іфтіхар Алі Ансарі

Завжди будьте доступні, якщо я підключаюся до WiFi. WiFi не означає, що він має підключення до Інтернету. Я хочу перевірити підключення до Інтернету, навіть якщо він має підключення до Wi-Fi. Чи можете ви мені допомогти?
Wesley

@wesley Як ти це вирішив?
Кезельме

145

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

Включіть 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 Це не робить перевірку Інтернету асинхронно, тому це "набагато стрункіше" ... Ви завжди повинні робити це асинхронно, підписуючи сповіщення, щоб ви не зависали додаток у цьому процесі.
iwasrobbed

Дякую, ця робота, навіть якщо ви використовуєте wifi adsl і adsl не підключений, саме те, що мені потрібно.
Віллі

5
Це просочує пам'ять - структуру "читабельності" (об'єкт, річ) потрібно звільнити за допомогою CFRelease ().
Рассел Малл

@RussellMull ... будь-яка ідея, як виправити витік?
i_raqz

Дивно, що ця відповідь передує моєму (на запитання, позначеному як дублікат) двома роками, точно таке ж, як і моє, але я його до сьогодні не бачив.
ArtOfWarfare

121

Це була правильна відповідь, але вона застаріла, тому що ви повинні передплатити сповіщення про доступність. Цей метод перевіряється синхронно:


Ви можете використовувати клас доступності 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) { }

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


6
Дивіться мій коментар вище про те, що таким чином не можна користуватися Reachability. Використовуйте його в асинхронному режимі та підписуйтесь на повідомлення, які він надсилає - не варто.
Kendall Helmstetter Gelner

Цей код є хорошою відправною точкою для речей, які потрібно встановити, перш ніж використовувати методи делегата для класу доступності.
Брок Вульф

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 - це шлях.

Обережно: це ненадовго заблокує ваш потік під час завантаження веб-сайту У моєму випадку це не було проблемою, але ви повинні врахувати це (заслуга Бреда за те, що він це вказав).


10
Мені дуже подобається ця ідея, але я б сказав, що за 99,999% надійності, зберігаючи невеликий розмір відповідей, перейдіть на www.google.com/m, який є мобільним видом для Google.
rwyland

1
Дивовижне рішення @Erik. Я також рекомендую вам використовувати www.google.com, а не www.google.com/m, як говорив rwyland. Це дивно, але з мого тесту мобільна версія завжди займає приблизно 120 мс більше, ніж www.google.com
вересня

4
Документи Apple рекомендують цього не робити, оскільки це може заблокувати потік у повільній мережі, може призвести до припинення роботи програми в iOS
Бред Томас

Дякуємо за позитивний відгук, погоджуйтеся, що www.google.com/m - найкраще рішення через надійність!
Ерік

3
LOL, я впевнений, що Google цінує, що ви пропонуєте людям використовувати їх як ресурс перевірки в Інтернеті.
mxcl

73

Ось як я це роблю в своїх додатках: Хоча код відповіді 200 не гарантує нічого, він для мене досить стабільний. Для цього не потрібно стільки завантаження, скільки відповіді NSData, розміщені тут, оскільки моя тільки перевіряє відповідь HEAD.

Швидкий код

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
        }
    })
}

Об'єктивно-С Кодекс

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
         }
    }];
}

3
Здається, це найшвидший шлях
Павло

3
Обережно: на мій досвід, це рішення не працює весь час. У багатьох випадках відповідь, що повертається, становить 403, після того, як вона пережила солодкий час. Це рішення здавалося ідеальним, але не гарантує 100% результатів.
Мустафа

10
Станом на червень 2014 року в Китаї це не вдасться, оскільки китайський уряд тепер повністю блокує сайт google.com. (Хоча google.cn працює, але в Китаї немає baidu.com, немає Інтернету) Напевно, краще прослухати будь-який сервер, з яким потрібно спілкуватися.
prewett

4
Замість цього скористайтеся www.appleiphonecell.com - Apple саме цю URL створила саме з цієї причини.
Smikey

1
Я використовував appleiphonecell як власний Apple, його можна використовувати і в Китаї, і це дуже швидкий веб-сайт. Це, у поєднанні з вашою відповіддю, забезпечило мені найближче і швидке рішення. Дякую
вересня 15:15

57

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

Примітка. Будь ласка, дивіться коментар @ KHG до цієї відповіді стосовно використання коду доступності Apple.


Дякую. Я виявив, що документація Xcode в 3.0 також містить вихідний код, знайдений шляхом пошуку "доступності" в документації.
Brock Woolf

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 надає зразок програми, який робить саме це:

Доступність


7
Слід зазначити, що зразок Reachability виявляє лише те, які інтерфейси є активними, а не які мають дійсне підключення до Інтернету. Програми повинні витончено вирішувати помилки, навіть коли Reachability повідомляє, що все готово до роботи.
rpetrich

На щастя, ситуація набагато краща в 3.0, оскільки система представить сторінку входу для користувачів за заблокованим Wi-Fi, де вам доведеться увійти в систему ... вам потрібно перевірити переспрямування вручну (а ви все ще робите якщо розробляються додатки 2.2.1)
Kendall Helmstetter Gelner

Я б не сказав, що додаток Reachability робить саме те, що просять. Однак це є гарною відправною точкою для додавання того виду функціональності, про який
Йохан Карлссон

Перерване посилання!, Вдячний, якщо це можна перевірити / виправити, велике спасибі
Хайдер Саті

33

Оновлено лише клас доступності. Тепер ви можете використовувати:

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, цей код не є асинхронним, і ви гарантовано зможете побачити його в Crash Reports - це сталося зі мною раніше.
бпапа

1
Я згоден з bpapa. Використовувати синхронний код не годиться. Дякую за інформацію, хоча
Брок Вульф



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).


цей код не зовсім хороший, оскільки він просто перевіряє, чи є у вас з'єднання 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 не означає, що він має підключення до Інтернету. Я хочу перевірити підключення до Інтернету, навіть якщо він має підключення до Wi-Fi. Чи можете ви мені допомогти?
Wesley

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;
}
}

7
Навіть якщо пристрій підключено до Wi-Fi або якогось іншого типу мережі, Інтернет-з'єднання все ще може бути недоступним. Простий тест: підключіться до домашнього wifi та відключіть кабельний модем. Досі підключений до wifi, але нульовий Інтернет.
iwasrobbed

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. Клас доступності

Для отримання додаткової інформації див. Доступність (Apple Developer).


1
Є два способи перевірити доступність Інтернету в iPhone SDK 1) Перевірте, чи відкрита сторінка Google чи ні.
IOS Rocks

1
-1: Це синхронний метод, який блокує основний потік (той, на який змінено інтерфейс програми), при цьому він намагається підключитися до google.com. Якщо ваш користувач перебуває на дуже повільному з’єднанні даних, телефон буде діяти так, що процес не відповідає.
iwasrobbed


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

Спочатку скачайте клас доступності та введіть файл X. X і 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

Клас досяжності ОК , щоб з'ясувати , якщо інтернет - з'єднання є пристрій чи ні ...

Але у випадку доступу до інтранет-ресурсу :

Пінгінг Інтранет-сервера класом доступності завжди повертає істину.

Тому швидким рішенням у цьому сценарії було б створити веб-метод, який називається pingmeразом з іншими веб-методами на сервісі. ThepingmeПовинен повернути що - то.

Тому я написав наступний метод про загальні функції

-(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.


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
Nikel Arteta

Не працює, якщо ви підключені до Wi-Fi без Інтернету.
Кезельме

6
  • Крок 1. Додайте клас доступності у свій проект.
  • Крок 2: Імпортуйте клас доступності
  • Крок 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");
    }

Документи Apple заявляють про це Примітка: Доступність не може повідомити вашій програмі, якщо ви можете підключитися до певного хоста, лише доступний інтерфейс, який може дозволити з'єднання, і чи цей інтерфейс є WWAN.
noobsmcgoobs
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.