检测载波连接类型(3G / EDGE / GPRS)

时间:2012-06-15 11:16:16

标签: iphone objective-c ios network-programming iphone-privateapi

如何获得运营商网络的连接类型?

  • 如果使用Reachability class
  • 连接是WIFI或WWAN,我就能获得
  • 我能够获得网络标志

      

    可达性标志状态:WR t ------ localWiFiStatusForFlags

  • 我可以使用CaptiveNetwork

  • 获取WIFI SSID
  

支持的接口:(en0)

en0 => {  
    BSSID = "xx:xx:xx:xx:xx:xx";  
    SSID = MyWifiNetwork;  
    SSIDDATA = <x1x1x1x1 x1x1x1x1 x1>;  
}  

但我无法区分3G,EDGE或GPRS连接。

任何想法也使用iOS私有API?

感谢。

4 个答案:

答案 0 :(得分:61)

从iOS 7开始,您可以使用:

CTTelephonyNetworkInfo *telephonyInfo = [CTTelephonyNetworkInfo new];
NSLog(@"Current Radio Access Technology: %@", telephonyInfo.currentRadioAccessTechnology);
[NSNotificationCenter.defaultCenter addObserverForName:CTRadioAccessTechnologyDidChangeNotification 
                                                object:nil 
                                                 queue:nil 
                                            usingBlock:^(NSNotification *note) 
{
    NSLog(@"New Radio Access Technology: %@", telephonyInfo.currentRadioAccessTechnology);
}];

我还发现这可以检测慢速或快速连接:

- (BOOL)isFast:(NSString*)radioAccessTechnology {
    if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyGPRS]) {
        return NO;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyEdge]) {
        return NO;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyWCDMA]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSDPA]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSUPA]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMA1x]) {
        return NO;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyeHRPD]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyLTE]) {
        return YES;
    }

    return YES;
}

答案 1 :(得分:5)

OLD解决方案,使用私有API ,特别是SoftwareUpdateServices.framework

Class NetworkMonitor = NSClassFromString(@"SUNetworkMonitor");
NSLog(@"TYPE: %d", [NetworkMonitor currentNetworkType]);

它返回:

  

0:没有数据
  1:WIFI
  2:GPRS / EDGE
  3:3G

希望这有助于社区。

答案 2 :(得分:1)

接受的答案不适用于iOS 10.我找到了一种解决方法,并在AppDelegate中设置了一个计时器,该计时器每隔5秒检查一次属性currentRadioAccessTechnology。因此,我们还需要一个功能来检查WIFI连接是否可用而不是无线接入技术。

检查WIFI连接是否可用:

class func isConnectedToWlan() -> Bool {
    var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, 
                         sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
    zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
    zeroAddress.sin_family = sa_family_t(AF_INET)

    let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
        $0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
            SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
        }
    }

    var flags: SCNetworkReachabilityFlags = SCNetworkReachabilityFlags(rawValue: 0)
    if SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) == false {
        return false
    }

    //Only Working for WIFI
     let isReachable = flags == .reachable
     let needsConnection = flags == .connectionRequired

     return isReachable && !needsConnection
}

像这样设置计时器:

Timer.scheduledTimer(timeInterval: TimeInterval.seconds(5.0), target: self, selector:      
                           #selector(showNetworkMessage), userInfo: nil, repeats: true)

每5秒调用一次的选择器:

    guard !Reachability.isConnecteToWlan() else {
        //Connected to WLAN
        return
    }
    guard let currentRadioAccessTechnology = info.currentRadioAccessTechnology else {
        // No internet connection
        return
    }
    guard (currentRadioAccessTechnology == CTRadioAccessTechnologyGPRS 
             || currentRadioAccessTechnology == CTRadioAccessTechnologyEdge) else {
        // 3G, LTE fast radio access Technology
        return
    }

    if lastRadioAccessTechnology != nil {
        guard let lastRadioAccessTechnology = lastRadioAccessTechnology, 
            (lastInfo != currentRadioAccessTechnology || 
              lastInfo != currentRadioAccessTechnology) else {
            //Internet connection did not change
            return
        }
    }
    // Internet connection changed to Edge or GPRS
    // Store lastRadioAccessTechnology to check if internet connection changed
    lastRadioAccessTechnology = currentRadioAccessTechnology

答案 3 :(得分:-1)

我正在开发一款iPhone应用程序,它需要能够识别当前使用的是哪种类型的互联网连接(Wifi,3G,Edge等)。我找到了一种使用Apples Reachability示例代码进行检查的简单方法。似乎有关于此在线的信息短缺,我希望这可以帮助某人。

首先将Reachability.m / .h复制到您的项目中,并将#include“Reachability.h”包含在您的班级中。

Reachability *reach = [[Reachability alloc]init];
if (reach.internetConnectionStatus == NotReachable) {
    NSLog(@"No Connection Found");
} else if (reach.internetConnectionStatus == ReachableViaCarrierDataNetwork) {
    NSLog(@"3G or Edge");
} else if (reach.internetConnectionStatus == ReachableViaWiFiNetwork) {
    NSLog(@"Wifi Connection");
}
[reach release];

此代码可能不是实现此目的的最佳方式,但它似乎是最简单的方法。