Como verificar se há uma conexão ativa com a Internet no iOS ou no macOS?

1326

Gostaria de verificar se tenho uma conexão com a Internet no iOS usando as bibliotecas Cocoa Touch ou no macOS usando as bibliotecas Cocoa .

Eu vim com uma maneira de fazer isso usando um NSURL. A maneira como fiz isso parece um pouco confiável (porque até o Google poderia um dia ficar inoperante e confiar em terceiros parece ruim), e enquanto eu poderia verificar se há uma resposta de outros sites, se o Google não responder, parece um desperdício e uma sobrecarga desnecessária no meu aplicativo.

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

O que fiz de ruim (sem mencionar que stringWithContentsOfURLfoi preterido no iOS 3.0 e no macOS 10.4) e, em caso afirmativo, qual é a melhor maneira de fazer isso?

Brock Woolf
fonte
11
Em vez disso return (BOOL)URLString;, ou melhor ainda, return !!URLStringoureturn URLString != nil
3
Não sei qual é o seu caso de uso, mas se você puder, é preferível tentar a solicitação e lidar com erros, como a falta de conexão que surgir. Se você não pode fazer isso, então existem muitos bons conselhos aqui neste caso.
SK9
2
Sua solução é inteligente e eu prefiro. Você também pode usar NSString *URLString = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"https://twitter.com/getibox"] encoding:NSUTF8StringEncoding error:nil];Para se livrar do aviso irritante.
Abdelrahman Eid
4
tente usar classe acessibilidade a partir do link abaixo, ele vai trabalhar para você github.com/tonymillion/Reachability
Dhaval H. Nena
4
Para aqueles que encontraram recentemente esta resposta: stackoverflow.com/a/8813279
afollestad 17/04/14

Respostas:

1285

Importante : Essa verificação sempre deve ser realizada de forma assíncrona. A maioria das respostas abaixo é síncrona, portanto, tenha cuidado, caso contrário, você congelará seu aplicativo.


Rápido

1) Instale via CocoaPods ou Carthage: https://github.com/ashleymills/Reachability.swift

2) Teste de acessibilidade via fechamentos

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

Objetivo-C

1) Adicione SystemConfigurationestrutura ao projeto, mas não se preocupe em incluí-la em qualquer lugar

2) Adicione a versão Reachability.he Reachability.mo projeto de Tony Million (encontrado aqui: https://github.com/tonymillion/Reachability )

3) Atualize a seção da interface

#import "Reachability.h"

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

4) Em seguida, implemente esse método no arquivo .m do seu controlador de exibição, que você pode chamar

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

Nota importante: A Reachabilityclasse é uma das classes mais usadas em projetos, portanto, você pode encontrar conflitos de nomenclatura com outros projetos. Se isso acontecer, você precisará renomear um dos pares de arquivos Reachability.he Reachability.mpara outra coisa para resolver o problema.

Nota: O domínio que você usa não importa. É apenas um teste para um gateway para qualquer domínio.

Fui roubado
fonte
4
@gonzobrains: o domínio que você usa não importa. É apenas um teste para um gateway para qualquer domínio.
iwasrobbed
3
@KaanDedeoglu É apenas um exemplo, use o domínio que você quiser. Simplesmente verifica se há um gateway para a Internet, não se o domínio está realmente disponível.
Iwasrobbed
1
Ah, você também precisa adicionar SystemConfiguration.frameworkao projeto (para o método 1).
wiseindy
2
Use www.appleiphonecell.com em vez de google.com - esse URL foi criado pela apple exatamente por esse motivo.
25715 Smikey
1
O uso de www.appleiphonecell.com é agora (2018) uma má escolha. Agora ele é redirecionado para Apple.com, que é um arquivo html> 40kB. De volta ao google.com - são apenas 11kB. BTW google.com/m tem o mesmo tamanho, mas é relatado que é mais lento em 120 ms.
precisa saber é o seguinte
311

Eu gosto de manter as coisas simples. A maneira como faço isso é:

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

Então, eu uso isso sempre que quero ver se tenho uma conexão:

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

Este método não espera por status de rede alterado para fazer as coisas. Apenas testa o status quando você solicita.

cannyboy
fonte
Oi @msec, você pode tentar uma solução Andrew Zimmer nesta página, ele funciona bem com adsl desconectado (e wi-fi ligado)
Williew
1
Para aqueles que apenas copiam e colam como eu fiz com o código acima. Adicione também SystemConfiguration.framework manualmente ou você receberá um erro de vinculação.
Iftikhar Ali Ansari
Sempre é acessível se eu conectar com o WiFi. WiFi não significa que ele esteja conectado à Internet. Quero verificar a conexão à Internet, mesmo que tenha conectividade Wi-Fi. Pode me ajudar por favor?
quer
@wesley Como você resolveu isso?
Keselme 8/01
146

Usando o código de acessibilidade da Apple, criei uma função que verificará isso corretamente sem que você precise incluir nenhuma classe.

Inclua o SystemConfiguration.framework no seu projeto.

Faça algumas importações:

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

Agora basta chamar esta função:

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

E o iOS 5 foi testado para você.

Andrew Zimmer
fonte
@JezenThomas Isso não executa a verificação da Internet de forma assíncrona, e é por isso que é "muito mais fino" ... Você deve sempre fazer isso de forma assíncrona assinando notificações para não desligar o aplicativo nesse processo.
iwasrobbed
Obrigado, este trabalho, mesmo se você estiver usando wifi adsl e adsl não estiver conectado, é exatamente o que eu preciso.
Williew 5/05
5
Isso vaza memória - a estrutura de 'legibilidade' (objeto, coisa) precisa ser liberada com CFRelease ().
Russell Mull
@RussellMull ... alguma idéia de como consertar o vazamento?
precisa saber é o seguinte
Estranho que essa resposta anteceda a minha (em uma pergunta marcada como duplicada) por 2 anos, é exatamente a mesma que a minha, mas eu nunca a vi até hoje.
ArtOfWarfare 30/01
122

Essa costumava ser a resposta correta, mas agora está desatualizada, pois você deve assinar as notificações de acessibilidade. Este método verifica de forma síncrona:


Você pode usar a classe de acessibilidade da Apple. Também permitirá que você verifique se o Wi-Fi está ativado:

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

A classe de alcançabilidade não é fornecida com o SDK, mas faz parte desse aplicativo de amostra da Apple . Basta fazer o download e copiar Reachability.h / m no seu projeto. Além disso, você precisa adicionar a estrutura SystemConfiguration ao seu projeto.

Daniel Rinser
fonte
6
Veja meu comentário acima sobre não usar a Acessibilidade dessa maneira. Use-o no modo assíncrono e assine as notificações enviadas - não.
Kendall Helmstetter Gelner
Esse código é um bom ponto de partida para as coisas que você precisa definir antes de poder usar os métodos delegados para a classe de acessibilidade.
Brock Woolf
82

Aqui está uma resposta muito simples:

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");

O URL deve apontar para um site extremamente pequeno. Eu uso o site para celular do Google aqui, mas se eu tivesse um servidor da Web confiável, faria o upload de um arquivo pequeno com apenas um caractere para obter a velocidade máxima.

Se verificar se o dispositivo está de alguma forma ligado à Internet é tudo o que você quer fazer, eu definitivamente recomendo usar esta solução simples. Se você precisar saber como o usuário está conectado, usar a Acessibilidade é o caminho a percorrer.

Cuidado: Isso bloqueará brevemente seu tópico enquanto ele carrega o site. No meu caso, isso não foi um problema, mas você deve considerar isso (créditos ao Brad por apontar isso).

Erik
fonte
10
Gosto muito dessa ideia, mas eu diria que, com 99,999% de confiabilidade e mantendo um tamanho pequeno de resposta, acesse www.google.com/m, que é a visualização móvel do Google.
rwyland
1
Solução impressionante @Erik. O que eu também recomendo é que você use o www.google.com, em vez do www.google.com/m, como disse a rwyland. É estranho, mas, no meu teste, a versão móvel sempre leva cerca de 120ms a mais do que o site www.google.com
Sebyddd
4
Docs da Apple recomenda não fazer isso uma vez que pode bloquear o thread em uma rede lenta, pode causar aplicativo para ser encerrado em iOS
Brad Thomas
Obrigado pelo feedback positivo, concordo que www.google.com/m é a melhor solução devido à confiabilidade!
Erik
3
LOL, tenho certeza que o Google gosta de sugerir que as pessoas as usem como um recurso de verificação da Internet.
Mxcl #
73

Aqui está como eu faço isso nos meus aplicativos: Embora um código de resposta de status 200 não garanta nada, ele é estável o suficiente para mim. Isso não exige tanto carregamento quanto as respostas do NSData postadas aqui, pois o meu apenas verifica a resposta HEAD.

Código Swift

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

Código 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
fonte
3
Parece que esta é a maneira mais rápida
Pavel
3
Cuidado: Na minha experiência, esta solução não funciona o tempo todo. Em muitos casos, a resposta retornada é 403, após um tempo agradável. Esta solução parecia perfeita, mas não garante 100% de resultados.
Mustafa
10
Em junho de 2014, isso falhará na China continental, devido ao governo chinês agora bloquear completamente o google.com. (google.cn funciona, porém, mas na China continental, sem baidu.com, sem internet) Provavelmente é melhor executar ping em qualquer servidor com o qual você precise se comunicar.
Prewett
4
Em vez disso, use www.appleiphonecell.com - a apple criou esse URL exatamente por esse motivo.
21715 Smikey
1
Eu usei appleiphonecell , pois é da Apple, também pode ser usado na China e é um site muito rápido. Isso, em conjunto com a sua resposta, me forneceu a solução mais próxima e mais rápida. Obrigado
Septronic
57

A Apple fornece um código de amostra para verificar os diferentes tipos de disponibilidade da rede. Como alternativa, há um exemplo no livro de receitas dos desenvolvedores do iPhone.

Nota: Consulte o comentário do @ KHG sobre esta resposta sobre o uso do código de acessibilidade da Apple.

teabot
fonte
Obrigado. Descobri que a documentação do Xcode no 3.0 também contém o código-fonte, encontrado pesquisando a "acessibilidade" na documentação.
Brock Woolf
7
Observe que a nova revisão (09-08-09) do código de exemplo de alcançabilidade da Apple é assíncrona.
precisa saber é o seguinte
46

Você pode usar Reachabilitypor  ( disponível aqui ).

#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.
Aleksander Azizi
fonte
@Supertecnoboff Não, é assíncrono.
Aleksander Azizi
39

A Apple fornece um aplicativo de exemplo que faz exatamente isso:

Acessibilidade

NANNAV
fonte
7
Observe que a amostra de alcançabilidade detecta apenas quais interfaces estão ativas, mas não quais possuem uma conexão válida com a Internet. Os aplicativos devem lidar normalmente com falhas, mesmo quando a Acessibilidade relatar que está tudo pronto.
Rpetrich 5/07/2009
Felizmente, a situação é muito melhor na versão 3.0, pois o sistema apresentará uma página de login para usuários atrás de um WiFi bloqueado no qual você precisa fazer login para usar ... você precisa verificar manualmente o redirecionamento (e ainda o faz se desenvolvendo 2.2.1 apps)
Kendall Helmstetter Gelner
Eu não diria que o aplicativo Acessibilidade faz exatamente o que é solicitado. No entanto, é um bom ponto de partida para adicionar o tipo de funcionalidade que é pediu,
Johan Karlsson
Link quebrado !, apreciaria se isso pudesse ser verificado / corrigido, muito obrigado
Heider Sati
33

Somente a classe de alcançabilidade foi atualizada. Agora você pode usar:

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");}
Ben Groot
fonte
1
A menos que algo tenha mudado desde o lançamento do 4.0, esse código não é assíncrono e você tem a garantia de vê-lo aparecer nos Crash Reports - aconteceu comigo antes.
Bpapa 27/08/2010
1
Eu concordo com o bpapa. Não é uma boa ideia usar código síncrono. Obrigado pela informação embora
Brock Woolf
25

Há uma modernização de acessibilidade de boa aparência, usando ARC e GCD aqui:

Acessibilidade

JK Laiho
fonte
22

Se você estiver usando, AFNetworkingpoderá usar sua própria implementação para o status de acessibilidade da Internet.

A melhor maneira de usar AFNetworkingé subclassificar oAFHTTPClient classe e usá-la para fazer suas conexões de rede.

Uma das vantagens de usar essa abordagem é que você pode usar blockspara definir o comportamento desejado quando o status de alcançabilidade for alterado. Supondo que eu criei uma subclasse singleton de AFHTTPClient(como dito nas "Notas de subclassificação" nos documentos da AFNetworking ) denominada BKHTTPClient, eu faria algo como:

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

Você também pode verificar se há conexões Wi-Fi ou WLAN usando especificamente as enumerações AFNetworkReachabilityStatusReachableViaWWANe AFNetworkReachabilityStatusReachableViaWiFi( mais aqui ).

Bruno Koga
fonte
18

Eu usei o código nesta discussão e parece funcionar bem (leia toda a tópico!).

Não testei exaustivamente com todos os tipos de conexão possíveis (como Wi-Fi ad hoc).

Felixyz
fonte
esse código não é totalmente bom porque apenas verifica se você possui uma conexão wifi com um roteador, e não se a web pode ser acessada. Você pode ter o wifi funcionando e continuar habilitado para acessar a web.
DuckDucking
15

Muito simples .... Tente estas etapas:

Etapa 1: adicione a SystemConfigurationestrutura ao seu projeto.


Etapa 2: importe o seguinte código no seu headerarquivo.

#import <SystemConfiguration/SystemConfiguration.h>

Etapa 3: Use o seguinte método

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

  • Tipo 2:

    Cabeçalho de importação :#import "Reachability.h"

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

Etapa 4: Como usar:

- (void)CheckInternet
{
    BOOL network = [self currentNetworkStatus];
    if (network)
    {
        NSLog(@"Network Available");
    }
    else
    {
        NSLog(@"No Network Available");
    }
}
Rajesh Loganathan
fonte
O tipo 1 é assíncrono?
Supertecnoboff
Quero as correções do tipo 2 da sua resposta. Eu adicionei as classes de acessibilidade e tentei verificar a verificação da conexão usando acima da sua resposta. ele sempre é acessível mesmo que eu conecte com o Wi-Fi, mas não possui conexão à Internet. WiFi não significa que ele esteja conectado à Internet. Quero verificar a conexão à Internet, mesmo que tenha conectividade Wi-Fi. Pode me ajudar por favor?
quer
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
fonte
7
Mesmo se o dispositivo estiver conectado ao Wifi ou a algum outro tipo de rede, a conexão à Internet ainda estará indisponível. Teste simples: conecte-se ao seu wifi em casa e desconecte o modem a cabo. Ainda conectado ao wifi, mas zero à internet.
precisa saber é o seguinte
11
- (void)viewWillAppear:(BOOL)animated
{
    NSString *URL = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]];

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

Ou use a classe de alcançabilidade .

Há duas maneiras de verificar a disponibilidade da Internet usando o iPhone SDK:

1. Verifique se a página do Google está aberta ou não.

2. Classe de acessibilidade

Para mais informações, consulte Acessibilidade (Apple Developer).

Rochas IOS
fonte
1
Existem duas maneiras de verificar a disponibilidade da Internet no iPhone SDK 1) Verifique se a página do Google está aberta ou não.
IOS Rocks
1
-1: este é um método síncrono que bloqueia o segmento principal (aquele em que a interface do aplicativo é alterada) enquanto tenta se conectar ao google.com. Se o usuário estiver com uma conexão de dados muito lenta, o telefone agirá como se o processo não respondesse.
iwasrobbed
10

Primeiro : adicionar CFNetwork.frameworkna estrutura

Código :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");
    }
}
Paresh Hirpara
fonte
8

Primeiro, baixe a classe de acessibilidade e coloque o arquivo reachability.he reachabilty.m no seu Xcode .

A melhor maneira é criar uma classe de funções comum (NSObject) para que você possa usá-la em qualquer classe. Estes são dois métodos para uma verificação de acessibilidade da conexão de rede:

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

Agora você pode verificar a conexão de rede em qualquer classe chamando esse método de classe.

Latika Tiwari
fonte
8

Há também outro método para verificar a conexão com a Internet usando o iPhone SDK.

Tente implementar o seguinte código para a conexão de rede.

#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;
}
Sahil Mahajan
fonte
8
  1. Faça o download do arquivo de acessibilidade, https://gist.github.com/darkseed/1182373

  2. E adicione CFNetwork.frameworke 'SystemConfiguration.framework' na estrutura

  3. Importe #import "Reachability.h"


Primeiro : adicionar CFNetwork.frameworkna estrutura

Código :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");
    }
}
Maulik Salvi
fonte
8

Swift 3 / Swift 4

Você deve primeiro importar

import SystemConfiguration

Você pode verificar a conexão à Internet com o seguinte método

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)

}
Devang Tandel
fonte
7

A classe Acessibilidade é OK para descobrir se a conexão com a Internet está disponível para um dispositivo ou não ...

Mas no caso de acessar um recurso da intranet :

Efetuar ping no servidor da intranet com a classe de alcançabilidade sempre retorna true.

Portanto, uma solução rápida nesse cenário seria criar um método da web chamado pingmejunto com outros métodos da web no serviço. O pingmedeve retornar algo.

Então, eu escrevi o seguinte método em funções comuns

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

O método acima foi muito útil para mim; portanto, sempre que tento enviar alguns dados para o servidor, sempre verifico a acessibilidade do meu recurso da intranet usando este URLRequest de tempo limite baixo.

Durai Amuthan.H
fonte
7

Fazer isso sozinho é extremamente simples. O método a seguir irá funcionar. Apenas certifique-se de não permitir que um protocolo de nome de host como HTTP, HTTPS etc. seja passado com o nome.

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

É rápido, simples e indolor.

Tony
fonte
7

Eu acho que essa é a melhor resposta.

"Sim" significa conectado. "Não" significa desconectado.

#import "Reachability.h"

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

    if (internetStats == NotReachable)
    {
        return NO;
    }
    else
    {
        return YES;
    }
}
Mina Fawzy
fonte
6

Importe a Reachable.hclasse no seu ViewControllere use o seguinte código para verificar a conectividade :

     #define hasInternetConnection [[Reachability reachabilityForInternetConnection] isReachable]
     if (hasInternetConnection){
           // To-do block
     }
Himanshu Mahajan
fonte
Sua resposta é exatamente o que estou procurando. Você senhor merece um voto se xD
Nikel Arteta
Não funciona se você estiver conectado a um WiFi sem internet.
Keselme 12/01
6
  • Etapa 1: adicione a classe de acessibilidade em seu projeto.
  • Etapa 2: Importar a classe Acessibilidade
  • Etapa 3: Crie a função abaixo

    - (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;
            }
        }
    }
  • Etapa 4: chame a função como abaixo:

    if (![self checkNetConnection]) {
        [GlobalFunctions showAlert:@""
                         message:@"Please connect to the Internet!"
                         canBtntitle:nil
                         otherBtnTitle:@"Ok"];
        return;
    }
    else
    {
        Log.v("internet is connected","ok");
    }
Anny
fonte
Os documentos da Apple declaram isso Nota: A acessibilidade não pode dizer ao seu aplicativo se você pode se conectar a um host específico, apenas que uma interface esteja disponível para permitir uma conexão e se essa interface é a WWAN.
precisa saber é o seguinte