ios - sozinho - itunes




Como verificar se há uma conexão ativa com a Internet no iOS ou no MacOS? (20)

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 NSURL uma maneira de fazer isso usando uma NSURL . A maneira como fiz isso parece um pouco incerta (porque mesmo o Google poderia estar um dia para baixo e depender de uma terceira parte parece ruim), e enquanto eu poderia verificar a resposta de alguns outros sites se o Google não respondesse, parece um desperdício desnecessário e uma sobrecarga na minha aplicação.

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

É o que eu fiz de ruim, (para não mencionar stringWithContentsOfURL é obsoleto no iOS 3.0 e macOS 10.4) e em caso afirmativo, qual é a melhor maneira de fazer isso?


  1. Baixe o arquivo Acessibilidade, https://gist.github.com/darkseed/1182373

  2. E adicione CFNetwork.frameworke 'SystemConfiguration.framework' no framework

  3. Do #import "Reachability.h"


Primeiro : adicionar CFNetwork.frameworkno quadro

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

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

Nota: Por favor, veja o comentário da @KHG sobre esta resposta em relação ao uso do código de acessibilidade da Apple.


Apenas a classe Reachability 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");}

Aqui está como eu faço isso em meus aplicativos: Embora um código de resposta de 200 status não garanta nada, ele é estável o suficiente para mim. Isso não requer tanto carregamento quanto as respostas NSData postadas aqui, já que 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.appleiphonecell.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 Apple's region universal URL reachable
        }
        else
        {
            // No "Internet" aka Apple's region universal URL un-reachable
        }
    })
}

Código Objetivo-C

typedef void(^connection)(BOOL);

- (void)checkInternet:(connection)block
{
    NSURL *url = [NSURL URLWithString:@"http://www.appleiphonecell.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 Apple's region universal URL reachable
         }
         else
         {
             // No "Internet" aka Apple's region universal URL un-reachable
         }
    }];
}

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

Você pode usar a classe de acessibilidade da Apple. Ele 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 Reachability não é fornecida com o SDK, mas sim uma parte desse aplicativo de amostra da Apple . Basta baixá-lo e copie o arquivo Acessibilidade.h / m para o seu projeto. Além disso, você precisa adicionar a estrutura SystemConfiguration ao seu projeto.


Eu gosto de manter as coisas simples. A maneira que eu 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 alterados para fazer coisas. Apenas testa o status quando você pede.



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

A melhor maneira de usar o AFNetworking é subclassificar a classe AFHTTPClient e usar essa classe para fazer suas conexões de rede.

Uma das vantagens de usar essa abordagem é que você pode usar blocks para definir o comportamento desejado quando o status de acessibilidade mudar. Supondo que eu criei uma subclasse singleton de AFHTTPClient (como dito no "Subclassing notes" em AFNetworking docs ) chamado 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 especificamente usando os enums AFNetworkReachabilityStatusReachableViaWiFi e AFNetworkReachabilityStatusReachableViaWiFi ( mais aqui ).


Usando o código Reachability da Apple, criei uma função que irá verificar isso corretamente sem que você precise incluir classes.

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 é só chamar essa 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 testado para você.



Importante : Essa verificação deve ser sempre executada de forma assíncrona. A maioria das respostas abaixo são síncronas, 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 através de 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 a estrutura SystemConfiguration ao projeto, mas não se preocupe em incluí-la em lugar algum

2) Adicione a versão de Reachability.h e Reachability.m Tony Million ao projeto (encontrada aqui: github.com/tonymillion/Reachability )

3) Atualize a seção de 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 este 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 classe Reachability é uma das classes mais usadas em projetos, portanto, você pode encontrar conflitos de nomenclatura com outros projetos. Se isso acontecer, você terá que renomear um dos pares de arquivos Reachability.m e Reachability.m para outra coisa para resolver o problema.

Nota: o domínio que você usa não importa. Está apenas testando um gateway para qualquer domínio.


Primeiro : adicionar CFNetwork.frameworkno quadro

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

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

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

Tente implementar o código a seguir 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;
}

A classe Reachability é 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 de intranet :

O ping do servidor de intranet com a classe de acessibilidade 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 alguma coisa.

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, então, sempre que tento enviar alguns dados para o servidor, sempre verifico a acessibilidade do meu recurso de intranet usando esse URLRequest de tempo limite baixo.



Fazer isso sozinho é extremamente simples. O método a seguir funcionará. Apenas certifique-se de não permitir que um protocolo de nome de host, como HTTP, HTTPS, etc., seja transmitido 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.


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

     #define hasInternetConnection [[Reachability reachabilityForInternetConnection] isReachable]
     if (hasInternetConnection){
           // To-do block
     }

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

- (void)viewWillAppear:(BOOL)animated
{
    NSString *URL = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com"]];

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

Ou use a classe Reachability .

Existem 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 Reachability (Apple Developer).







reachability