iOS Detect 3G ou WiFi

106

Não tenho certeza se isso é possível, mas tenho esse cenário.

Eu tenho um site exibido no meu UIWebView que tem o link definido em um UISegmentedController. O site deles pode detectar se você está em wi-fi ou na rede 3G.

Agora, o controlador segmentado aponta para 2 páginas diferentes: 1 - Uma tela de login amigável para iPhone 2 - A página inicial, uma vez que você esteja logado.

Agora, aqui está a questão:

Posso programar meu aplicativo para detectar se é para WIFI ou 3G (sei que você pode fazer isso), mas com base na resposta, vá para o segmento 1 ou 2

Mais ou menos assim:

if (iPhone device is on 3g) {
    Go to Segment 1;
} else {
    Go to Segment 0;
}
jwknz
fonte
2
possível duplicata do iphone SDK detecta rede Wifi e operadora
Andrejs Cainikovs

Respostas:

210

Usando o código que a Apple forneceu aqui

Reachability *reachability = [Reachability reachabilityForInternetConnection];
[reachability startNotifier];

NetworkStatus status = [reachability currentReachabilityStatus];

if(status == NotReachable) 
{
    //No internet
}
else if (status == ReachableViaWiFi)
{
    //WiFi
}
else if (status == ReachableViaWWAN) 
{
    //3G
}
James Webster
fonte
Sim Legal funcionou !!! Tive que fazer alguns consertos nos arquivos de acessibilidade, pois eles continham erros para iOS5 - mas estou muito feliz agora. Infelizmente, só posso dar a vocês 1 voto :-)
jwknz
10
Você não deveria ligar [reachability stopNotifier]depois de ter o status?
zekel
3
Isso depende do escopo em que você usa este código. Se isso fosse apenas em um método, reachabilitysairia do escopo e seria desalocado no final do método e stopNotifierseria chamado implicitamente.
James Webster
Obrigado pela edição. Presumo que era uma versão antiga deste código que usavaReachableViaWifiNetwork
James Webster
Isso funciona muito bem, mas não se esqueça de incluir no projeto geral systemConfiguration.framework, caso contrário, você obterá o problema do Linker
Jevgenij Kononov
30

Se você não deseja importar a biblioteca de acessibilidade ou lidar com notificadores, pode usar este método síncrono simples:

typedef enum {
    ConnectionTypeUnknown,
    ConnectionTypeNone,
    ConnectionType3G,
    ConnectionTypeWiFi
} ConnectionType;


+ (ConnectionType)connectionType
{
    SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, "8.8.8.8");
    SCNetworkReachabilityFlags flags;
    BOOL success = SCNetworkReachabilityGetFlags(reachability, &flags);
    CFRelease(reachability);
    if (!success) {
        return ConnectionTypeUnknown;
    }
    BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0);
    BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0);
    BOOL isNetworkReachable = (isReachable && !needsConnection);

    if (!isNetworkReachable) {
        return ConnectionTypeNone;
    } else if ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0) {
        return ConnectionType3G;
    } else {
        return ConnectionTypeWiFi;
    }
}
Pavel Alexeev
fonte
Para usar este código útil, você deve #import <SystemConfiguration / SystemConfiguration.h> e vincular a SystemConfiguration.framework.
Dirk de
18

Importe a acessibilidade da Apple e experimente isso,

#import "Reachability.h"
#import <CoreTelephony/CTTelephonyNetworkInfo.h>

//Try this
Reachability *reachability = [Reachability reachabilityForInternetConnection];
    [reachability startNotifier];

    NetworkStatus status = [reachability currentReachabilityStatus];

    if(status == NotReachable)
    {
       NSLog(@"none");
        //No internet
    }
    else if (status == ReachableViaWiFi)
    {
        NSLog(@"Wifi");
        //WiFi
    }
    else if (status == ReachableViaWWAN)
    {
        NSLog(@"WWAN");


    //connection type
    CTTelephonyNetworkInfo *netinfo = [[CTTelephonyNetworkInfo alloc] init];
    _carrier = [[netinfo subscriberCellularProvider] carrierName];

    if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyGPRS]) {
        NSLog(@"2G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyEdge]) {
        NSLog(@"2G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyWCDMA]) {
        NSLog(@"3G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSDPA]) {
        NSLog(@"3G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSUPA]) {
        NSLog(@"3G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMA1x]) {
        NSLog(@"2G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0]) {
        NSLog(@"3G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA]) {
        NSLog(@"3G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB]) {
        NSLog(@"3G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyeHRPD]) {
        NSLog(@"3G");
    } else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyLTE]) {
        NSLog(@"4G");
    }

    }

Referências (links podem quebrar no futuro):

Mohammad Zaid Pathan
fonte
Primeiro adicione a estrutura SystemConfiguration, abra este link github.com/tonymillion/Reachabilit 'e baixe o arquivo e copie Reachability.h, .m para seu projeto e importe #import "Reachability.h", #import <CoreTelephony / CTTelephonyNetworkInfo.h> e, finalmente, copie e cole o código acima ...
Marcando
8

Eu fiz um invólucro de Reachability baseado em bloco bastante simples que remove todo o código de Reachability semelhante a C desatualizado, colocado em uma forma muito mais Cocoa.

Uso como:

[EPPZReachability reachHost:hostNameOrIPaddress
               completition:^(EPPZReachability *reachability)
{
    if (reachability.reachableViaCellular) [self doSomeLightweightStuff];
}];

Consulte Acessibilidade com blocos para uso diário no blog eppz! Ou pegue-o diretamente de acessibilidade do eppz! No GitHub .

Ele também funciona com endereços IP , o que se revelou um recurso de invólucro de Alcance muito raro.

Geri Borbás
fonte
19
Ummm, por que a 'captura de tela'?
QED de
12
Peguei na postagem do blog, doce para os olhos.
Geri Borbás
6

Ao usar o iOS 12 ou mais recente, você pode usar em NWPathMonitorvez da Reachabilityclasse pré-histórica :

import Network // Put this on top of your class

let monitor = NWPathMonitor()

monitor.pathUpdateHandler = { path in
    if path.status != .satisfied {
        // Not connected
    }
    else if path.usesInterfaceType(.cellular) {
        // Cellular 3/4/5g connection
    }
    else if path.usesInterfaceType(.wifi) {
        // Wi-fi connection
    }
    else if path.usesInterfaceType(.wiredEthernet) {
        // Ethernet connection
    }
}

monitor.start(queue: DispatchQueue.global(qos: .background))
Ely
fonte
Podemos definir qual host testar para isso, como poderíamos fazer Reachability.reachabilityWithHostName?
agirault
5

Para o rápido, podemos usar:

func getNetworkType()->String {
    do{
        let reachability:Reachability = try Reachability.reachabilityForInternetConnection()
        do{
            try reachability.startNotifier()
            let status = reachability.currentReachabilityStatus
            if(status == .NotReachable){
                return ""
            }else if (status == .ReachableViaWiFi){
                return "Wifi"
            }else if (status == .ReachableViaWWAN){
                let networkInfo = CTTelephonyNetworkInfo()
                let carrierType = networkInfo.currentRadioAccessTechnology
                switch carrierType{
                case CTRadioAccessTechnologyGPRS?,CTRadioAccessTechnologyEdge?,CTRadioAccessTechnologyCDMA1x?: return "2G"
                case CTRadioAccessTechnologyWCDMA?,CTRadioAccessTechnologyHSDPA?,CTRadioAccessTechnologyHSUPA?,CTRadioAccessTechnologyCDMAEVDORev0?,CTRadioAccessTechnologyCDMAEVDORevA?,CTRadioAccessTechnologyCDMAEVDORevB?,CTRadioAccessTechnologyeHRPD?: return "3G"
                case CTRadioAccessTechnologyLTE?: return "4G"
                default: return ""
                }

                // Get carrier name

            }else{
                return ""
            }
        }catch{
            return ""
        }

    }catch{
        return ""
    }


}
Sachin Agarwal
fonte
3

O método da classe é o seguinte

+(NSString*)connectedNetworkType {
     Reachability *reachability = [Reachability reachabilityForInternetConnection];
        [reachability startNotifier];

        NetworkStatus status = [reachability currentReachabilityStatus];

        if(status == NotReachable) {
            NSLog(@"none");
            //No internet
        }
        else if (status == ReachableViaWiFi) {
            NSLog(@"Wifi");
            //WiFi
            return @"Wifi";
        }
        else if (status == ReachableViaWWAN){
            NSLog(@"WWAN");
            //connection type
            CTTelephonyNetworkInfo *netinfo = [[CTTelephonyNetworkInfo alloc] init];
            //    _carrier = [[netinfo subscriberCellularProvider] carrierName];
            if (([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyGPRS])
                ||([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyEdge])
                ||([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMA1x])) {
                NSLog(@"2G");
                return @"2G";
            }
            else if (([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyWCDMA])
                     ||([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSDPA])
                     ||([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSUPA])
                     ||([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0])
                     ||([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA])
                     ||([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB])
                     ||([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyeHRPD])){
                NSLog(@"3G");
                return @"3G";
            }
            else if ([netinfo.currentRadioAccessTechnology isEqualToString:CTRadioAccessTechnologyLTE]) {
                NSLog(@"4G");
                return @"4G";

            }
        }
        return @"-1";//default unknown
}
HDdeveloper
fonte
2
#import <ifaddrs.h>
#import <arpa/inet.h>

BOOL CheckWiFi() {

    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;

    BOOL hasWifi = NO;

    int err = getifaddrs(&interfaces);
    if(err == 0) {

        temp_addr = interfaces; 

        while(temp_addr) {

            if(temp_addr->ifa_addr->sa_family == AF_INET) {

                struct sockaddr_in *addr = (struct sockaddr_in *)temp_addr->ifa_addr;

                if(memcmp(temp_addr->ifa_name, "en", 2) == 0) {
                    hasWifi = YES;
                    break;
                }
            }

            temp_addr = temp_addr->ifa_next;
        }
    }

    freeifaddrs(interfaces);
    return hasWifi;
}

Para verificar se você está em um wi-fi, isso evita o custo de fazer uma conexão. Verifique se há ifa_name "ponte" para verificar se há compartilhamento de Internet.

Hogdotmac
fonte
0

Aqui está uma versão atualizada para iOS 6 com SimplePing da apple também incluído. É compatível com ARC e comecei com a correção de outra pessoa para Reachability. http://elbsolutions.com/projects/reachability-with-simpleping-wrapper/

Espero que isso ajude alguém.

Etienne Bley
fonte
Se você pudesse um exemplo de seu uso.
Mike D
-2

Use este, construído com Acessibilidade e fácil de usar, apenas algumas linhas de código para integrar. Tem uma função de retorno de chamada para avisar quando a conexão mudou http://huytd.github.io/datatify/

Huy Tran
fonte
Este uso novamente Acessibilidade
Stephan