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;
}
jwknz.dll
sumber
2
kemungkinan duplikat SDK iphone mendeteksi jaringan Wifi dan Operator
Andrejs Cainikovs

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
}
James Webster
sumber
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;
    }
}
Pavel Alexeev
sumber
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):

Mohammad Zaid Pathan
sumber
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.

Geri Borbás
sumber
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))
Ely
sumber
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 ""
    }


}
Sachin Agarwal
sumber
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
}
HDdeveloper
sumber
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.

Hogdotmac
sumber