iOS 3G veya WiFi Algılama


106

Bunun mümkün olup olmadığından emin değilim ama bu senaryoya sahibim.

Bir UISegmentedController'da ayarlanan bağlantıya sahip UIWebView'da görüntülenen bir web sitem var. Web sitesi, wifi veya 3g ağında olup olmadığınızı tespit edebilir.

Artık bölümlere ayrılmış denetleyici 2 farklı sayfayı işaret ediyor: 1 - iPhone dostu bir oturum açma ekranı 2 - Oturum açtıktan sonra ana sayfa.

Şimdi soru şu:

Uygulamamı WIFI mı yoksa 3G mi olduğunu tespit edecek şekilde programlayabilir miyim (bunu yapabileceğinizi biliyorum), ancak daha sonra cevaba göre segment 1 veya 2'ye gidin

Bunun gibi bir çeşit:

if (iPhone device is on 3g) {
    Go to Segment 1;
} else {
    Go to Segment 0;
}

Yanıtlar:


210

Apple'ın burada sağladığı kodu kullanarak

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
}

Evet Harika işe yaradı !!! Erişilebilirlik dosyalarının içinde iOS5 için hatalar olduğu için bazı düzeltmeler yapmak zorunda kaldım - ama şu anda çok mutluyum. Ne yazık ki size sadece 1
artı

10
[reachability stopNotifier]Durumu aldıktan sonra araman gerekmiyor mu?
zekel

3
Bu, bu kodu kullandığınız kapsama bağlıdır. Bu sadece bir yöntemde reachabilityolsaydı, kapsam dışına çıkar ve yöntemin sonunda serbest bırakılır ve stopNotifierörtük olarak çağrılırdı.
James Webster

Düzenleme için teşekkürler. Bunun kullanılan kodun eski bir sürümü olduğunu varsayıyorumReachableViaWifiNetwork
James Webster

Bu harika çalışıyor, ancak genel systemConfiguration.framework projesine dahil etmeyi unutmayın, aksi takdirde Linker sorunu yaşarsınız
Jevgenij Kononov

30

Erişilebilirlik kitaplığını içe aktarmak veya bildiricilerle uğraşmak istemiyorsanız, bu basit zaman uyumlu yöntemi kullanabilirsiniz:

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

Bu yararlı kodu kullanmak için, #import <SystemConfiguration / SystemConfiguration.h> ve SystemConfiguration.framework bağlantısına bağlanmanız gerekir.
Dirk

18

Apple'ın Erişilebilirliğini içe aktarın ve bunu deneyin,

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

    }

Referanslar (Gelecekte bağlantılar kopabilir):


Öncelikle SystemConfiguration çerçevesini ekleyin, bu bağlantıyı github.com/tonymillion/Reachabilit 'açın ve dosyayı indirin ve Reachability.h, .m dosyasını projenize kopyalayın ve #import "Reachability.h", #import <CoreTelephony / CTTelephonyNetworkInfo.h> içe aktarın ve son olarak ..... yukarıdaki kodu kopyalayıp yapıştırın
İşaretleme

8

Tüm güncelliğini yitirmiş C benzeri Erişilebilirlik kodunu kaldırıp çok daha fazla Kakao formuna dökülen oldukça basit bir blok tabanlı Erişilebilirlik sarmalayıcısı yaptım.

Gibi kullanım:

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

Bkz günlük kullanım için bloklarla Ulaşılabilirlik de eppz! Blog veya doğrudan yakala GitHub'dan de eppz! Erişilebilirlik .

Ayrıca , oldukça nadir bir Erişilebilirlik sarmalayıcı özelliği olduğu ortaya çıkan IP adresleriyle de çalışır .


19
Ummm neden 'ekran görüntüsü'?
2013

12
Blog yazısından aldım, gözler için şeker.
Geri Borbás

7

İOS 12 veya daha yenisini kullanırken, NWPathMonitortarih öncesi Reachabilitysınıf yerine kullanabilirsiniz :

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

Bunun için hangi ana bilgisayarı test edeceğimiz gibi, tanımlayabilir miyiz Reachability.reachabilityWithHostName?
agirault

5

Hızlı için şunları kullanabiliriz:

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


}

3

Sınıf yöntemi aşağıdaki gibidir

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

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

Bir kablosuz bağlantıda olup olmadığınızı kontrol etmek için, bu, bağlantı kurmanın maliyetli kontrolünden kurtarır. İnternet paylaşımını kontrol etmek için ifa_name "köprüsünü" kontrol edin.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.