iOS Mendeteksi 3G atau WiFi


106

Saya tidak yakin apakah ini mungkin, tetapi saya memiliki skenario ini.

Saya memiliki situs web yang ditampilkan di UIWebView saya yang tautannya disetel di UISegmentedController. Situs web mereka dapat mendeteksi jika Anda menggunakan wifi atau di jaringan 3g.

Sekarang pengontrol tersegmentasi menunjuk ke 2 halaman berbeda: 1 - Layar login ramah iPhone 2 - Halaman beranda, setelah Anda masuk.

Sekarang inilah pertanyaannya:

Dapatkah saya memprogram aplikasi saya untuk mendeteksi apakah itu untuk WIFI atau 3G (saya tahu Anda dapat melakukan ini), tetapi kemudian berdasarkan jawaban pergi ke segmen 1 atau 2

Jenis seperti ini:

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

Jawaban:


210

Menggunakan kode yang telah disediakan Apple di sini

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
}

Ya Keren itu berhasil !!! Harus melakukan beberapa perbaikan pada file yang dapat dijangkau karena ada kesalahan untuk iOS5 di dalamnya - tetapi saya sangat senang sekarang. Sayangnya saya hanya bisa memberi Anda 1 suara :-)
jwknz

10
Bukankah Anda harus menelepon [reachability stopNotifier]setelah Anda memiliki status?
zekel

3
Itu bergantung pada cakupan tempat Anda menggunakan kode ini. Jika ini hanya dalam sebuah metode, reachabilityakan keluar dari ruang lingkup dan dibatalkan alokasinya pada akhir metode dan stopNotifierakan dipanggil secara implisit.
James Webster

Terima kasih atas pengeditannya. Saya berasumsi itu adalah versi lama dari kode ini yang digunakanReachableViaWifiNetwork
James Webster

Itu berfungsi dengan baik, tetapi jangan lupa sertakan dalam proyek systemConfiguration.framework umum, jika tidak Anda akan mendapatkan masalah Linker
Jevgenij Kononov

30

Jika Anda tidak ingin mengimpor perpustakaan Reachability atau berurusan dengan pemberi tahu, Anda dapat menggunakan metode sinkron sederhana ini:

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

Untuk menggunakan kode yang berguna ini, Anda harus #import <SystemConfiguration / SystemConfiguration.h> dan menautkan ke SystemConfiguration.framework.
Dirk

18

Impor Reachability Apple dan coba ini,

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

    }

Referensi (Tautan mungkin rusak di masa mendatang):


Pertama tambahkan framework SystemConfiguration, buka tautan ini github.com/tonymillion/Reachabilit 'dan unduh file dan salin Reachability.h, .m ke proyek Anda dan impor #import "Reachability.h", #import <CoreTelephony / CTTelephonyNetworkInfo.h> dan terakhir copy paste kode di atas .....
Menandai

8

Saya membuat pembungkus Reachability berbasis blok yang cukup sederhana yang menghapus semua kode Reachability seperti C yang sudah ketinggalan zaman, dituangkan ke dalam bentuk Cocoa yang jauh lebih banyak.

Penggunaan seperti:

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

Lihat Reachability with blocks untuk penggunaan sehari-hari di blog eppz ! , atau ambil langsung dari jangkauan eppz! Di GitHub .

Ia juga bekerja dengan alamat IP , yang ternyata merupakan fitur pembungkus Reachability yang cukup langka.


19
Ummm kenapa 'screenshot'?
QED

12
Saya mendapatkannya dari posting blog, permen untuk mata.
Geri Borbás

6

Saat menggunakan iOS 12 atau yang lebih baru, Anda dapat menggunakan NWPathMonitorsebagai pengganti Reachabilitykelas prasejarah :

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

Bisakah kita menentukan host apa yang akan diuji untuk itu, seperti yang bisa kita lakukan Reachability.reachabilityWithHostName?
Agirault

5

Untuk cepat kita bisa menggunakan:

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

Metode kelas adalah sebagai berikut

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

Untuk memeriksa apakah Anda menggunakan wifi, ini menghemat biaya pembuatan koneksi yang mahal. Periksa ifa_name "jembatan" untuk memeriksa berbagi internet.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.