iOS ตรวจจับ 3G หรือ WiFi


106

ฉันไม่แน่ใจว่าเป็นไปได้หรือไม่ แต่ฉันมีสถานการณ์นี้

ฉันมีเว็บไซต์ที่แสดงใน UIWebView ของฉันซึ่งมีการตั้งค่าลิงก์ใน UISegmentedController เว็บไซต์ของพวกเขาสามารถตรวจจับได้ว่าคุณใช้ wifi หรือบนเครือข่าย 3g

ตอนนี้คอนโทรลเลอร์ที่แบ่งส่วนจะชี้ไปยัง 2 หน้าที่แตกต่างกัน: 1 - หน้าจอเข้าสู่ระบบที่เป็นมิตรกับ iPhone 2 - หน้าแรกเมื่อคุณเข้าสู่ระบบ

นี่คือคำถาม:

ฉันสามารถตั้งโปรแกรมให้แอปพลิเคชันตรวจจับได้หรือไม่ว่าเป็น WIFI หรือ 3G (ฉันรู้ว่าคุณทำได้) แต่จากคำตอบไปที่ส่วน 1 หรือ 2

ประเภทนี้:

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

คำตอบ:


210

โดยใช้รหัสที่ Apple ให้ไว้ที่นี่

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
}

ใช่มันได้ผล !!! ต้องทำการแก้ไขไฟล์ความสามารถในการเข้าถึงเนื่องจากมีข้อผิดพลาดสำหรับ iOS5 อยู่ในนั้น - แต่ตอนนี้ฉันมีความสุขมาก น่าเสียดายที่ฉันสามารถโหวตให้คุณได้เพียง 1 ครั้งเท่านั้น :-)
jwknz

10
คุณไม่ควรโทรหา[reachability stopNotifier]หลังจากที่คุณมีสถานะ?
zekel

3
ขึ้นอยู่กับขอบเขตที่คุณใช้รหัสนี้ หากนี่เป็นเพียงวิธีการหนึ่งreachabilityจะออกนอกขอบเขตและถูกยกเลิกการจัดสรรเมื่อสิ้นสุดวิธีการและstopNotifierจะเรียกโดยปริยาย
James Webster

ขอบคุณสำหรับการแก้ไข ฉันคิดว่ามันเป็นรหัสรุ่นเก่าที่ใช้ReachableViaWifiNetwork
James Webster

ใช้งานได้ดี แต่อย่าลืมรวมไว้ใน systemConfiguration.framework ทั่วไปของโครงการมิฉะนั้นคุณจะได้รับปัญหา Linker
Jevgenij Kononov

30

หากคุณไม่ต้องการนำเข้าไลบรารีการเข้าถึงหรือจัดการกับการแจ้งเตือนคุณสามารถใช้วิธีซิงโครนัสง่ายๆนี้:

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

ในการใช้รหัสที่เป็นประโยชน์นี้คุณต้อง #import <SystemConfiguration / SystemConfiguration.h> และลิงก์ไปที่ SystemConfiguration.framework
Dirk

18

นำเข้าความสามารถในการเข้าถึงของ Apple แล้วลองสิ่งนี้

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

    }

การอ้างอิง (ลิงก์อาจพังในอนาคต):


ขั้นแรกให้เพิ่ม SystemConfiguration framework เปิดลิงก์นี้github.com/tonymillion/Reacoveryit 'และดาวน์โหลดไฟล์และคัดลอก Reachability.h, .m ไปยังโปรเจ็กต์ของคุณและนำเข้า #import "Reachability.h", #import <CoreTelephony / CTTelephonyNetworkInfo.h> และสุดท้ายคัดลอกวางโค้ดด้านบน .....
ทำเครื่องหมาย

8

ฉันสร้างกระดาษห่อหุ้ม Reachability แบบบล็อกที่เรียบง่ายซึ่งดึงรหัสการเข้าถึงแบบ C ที่ล้าสมัยทั้งหมดเทลงในรูปแบบโกโก้มากขึ้น

การใช้งานเช่น:

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

ดูความสามารถในการเข้าถึงด้วยบล็อกสำหรับการใช้งานในชีวิตประจำวันที่eppz! blogหรือคว้าโดยตรงจากeppz! reachability ที่ GitHubGitHub

นอกจากนี้ยังทำงานร่วมกับที่อยู่ IPซึ่งกลายเป็นคุณสมบัติ Reachability wrapper ที่หายาก


19
อืมทำไมต้องเป็น "ภาพหน้าจอ"
QED

12
ฉันได้มาจากบล็อกโพสต์ขนมสำหรับตา
Geri Borbás

7

เมื่อใช้ iOS 12 หรือใหม่กว่าคุณสามารถใช้NWPathMonitorแทนReachabilityคลาสก่อนประวัติศาสตร์ได้:

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

เราสามารถกำหนดโฮสต์ที่จะทดสอบเช่นที่เราทำได้ Reachability.reachabilityWithHostNameหรือไม่?
agirault

5

เพื่อความรวดเร็วเราสามารถใช้:

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

วิธีการเรียนมีดังต่อไปนี้

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

หากต้องการตรวจสอบว่าคุณอยู่ใน wifi หรือไม่การดำเนินการนี้จะช่วยประหยัดค่าใช้จ่ายในการตรวจสอบการเชื่อมต่อ ตรวจสอบ ifa_name "bridge" เพื่อตรวจสอบการแชร์อินเทอร์เน็ต


1

หากคุณใช้ Xamarin หรือ Monotouch คุณสามารถใช้คลาส Reachability ดัดแปลงจากที่เก็บ Xamarin GitHub:

https://github.com/xamarin/monotouch-samples/blob/master/ReachabilitySample/reachability.cs

เพิ่มลงในโครงการของคุณและโทร Reachability.InternetConnectionStatus()


ลิงค์เสีย
Christopher Stephan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.