iOS phát hiện 3G hoặc WiFi


106

Tôi không chắc liệu điều này có khả thi không, nhưng tôi có kịch bản này.

Tôi có một trang web được hiển thị trong UIWebView của mình có liên kết được đặt trong UISegmentedController. Trang web của họ có thể phát hiện xem bạn đang sử dụng wifi hoặc trên mạng 3g.

Bây giờ bộ điều khiển được phân đoạn trỏ đến 2 trang khác nhau: 1 - Màn hình đăng nhập thân thiện với iPhone 2 - Trang chủ, khi bạn đã đăng nhập.

Bây giờ đây là câu hỏi:

Tôi có thể lập trình ứng dụng của mình để phát hiện xem nó là WIFI hay 3G (tôi biết bạn có thể làm điều này), nhưng sau đó dựa trên câu trả lời, hãy chuyển đến phân đoạn 1 hoặc 2

Kiểu như thế này:

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

Câu trả lời:


210

Sử dụng mã mà Apple đã cung cấp tại đây

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
}

Có Mát nó đã hoạt động !!! Đã phải sửa một số tệp có thể truy cập được vì chúng có lỗi đối với iOS5 trong đó - nhưng tôi rất vui ngay bây giờ. Thật không may, tôi chỉ có thể cho bạn 1 phiếu bầu :-)
jwknz 29/10/11

10
Bạn không nên gọi [reachability stopNotifier]sau khi bạn có trạng thái?
zekel

3
Điều đó phụ thuộc vào phạm vi mà bạn sử dụng mã này. Nếu điều này chỉ nằm trong một phương thức, reachabilitynó sẽ nằm ngoài phạm vi và được thỏa thuận ở cuối phương thức và stopNotifiersẽ được gọi ngầm định.
James Webster

Cảm ơn vì đã chỉnh sửa. Tôi cho rằng đó là một phiên bản cũ của mã này được sử dụngReachableViaWifiNetwork
James Webster

Đó là hoạt động tuyệt vời, nhưng đừng quên đưa vào systemConfiguration.framework chung dự án, nếu không bạn sẽ nhận được Linker vấn đề
Jevgenij Kononov

30

Nếu bạn không muốn nhập thư viện Khả năng tiếp cận hoặc xử lý trình thông báo, bạn có thể sử dụng phương pháp đồng bộ đơn giản sau:

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

Để sử dụng mã hữu ích này, bạn phải #import <SystemConfiguration / SystemConfiguration.h> và liên kết đến SystemConfiguration.framework.
Dirk

18

Nhập Khả năng tiếp cận của Apple và thử điều này,

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

    }

Tham khảo (Liên kết có thể bị hỏng trong tương lai):


Đầu tiên, hãy thêm khung SystemConfiguration, mở liên kết này github.com/tonymillion/Reachabilit 'và tải xuống tệp và sao chép Reachability.h, .m vào dự án của bạn và nhập #import "Reachability.h", #import <CoreTelephony / CTTelephonyNetworkInfo.h> và cuối cùng sao chép, dán đoạn mã trên .....
Đánh dấu

8

Tôi đã tạo một trình bao bọc Khả năng tiếp cận dựa trên khối khá đơn giản để loại bỏ tất cả mã Khả năng tiếp cận giống C đã lỗi thời, đổ vào một dạng Ca cao hơn nhiều.

Cách sử dụng như:

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

Xem Khả năng tiếp cận với các khối để sử dụng hàng ngày tại blog eppz! Hoặc tải trực tiếp từ eppz! Khả năng tiếp cận tại GitHub .

cũng hoạt động với địa chỉ IP , hóa ra là một tính năng bao bọc Khả năng tiếp cận khá hiếm.


19
Ummm tại sao lại là 'ảnh chụp màn hình'?
QED

12
Tôi đã có nó từ bài đăng trên blog, kẹo cho đôi mắt.
Geri Borbás

6

Khi sử dụng iOS 12 trở lên, bạn có thể sử dụng NWPathMonitorthay vì Reachabilitylớp trước đây:

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

Chúng tôi có thể xác định máy chủ nào để kiểm tra điều đó, giống như chúng tôi có thể với Reachability.reachabilityWithHostName?
agirault

5

Để nhanh chóng, chúng ta có thể sử dụng:

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

Phương pháp lớp như sau

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

Để kiểm tra xem bạn có đang sử dụng wifi hay không, điều này giúp tiết kiệm chi phí kiểm tra kết nối. Kiểm tra ifa_name "cầu nối" để kiểm tra chia sẻ internet.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.